Spring
server.forward-headers-strategy
NATIVE
FRAMEWORK
web configuration

Spring server.forward-headers-strategy NATIVE vs FRAMEWORK

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

When your Spring Boot application sits behind a reverse proxy such as Nginx, AWS ALB, or a Kubernetes Ingress controller, the proxy strips the original request details and replaces them with its own. The server.forward-headers-strategy property tells Spring how to recover the real client IP, protocol, host, and port from the X-Forwarded-* or Forwarded headers the proxy attaches. The two main values are NATIVE and FRAMEWORK, and picking the wrong one leads to incorrect redirect URLs, broken HTTPS detection, and misleading access logs.

What Forward Headers Carry

Proxy servers insert headers to pass along the original request metadata that would otherwise be lost. The most common headers are:

HeaderPurpose
X-Forwarded-ForOriginal client IP address
X-Forwarded-ProtoOriginal protocol (http or https)
X-Forwarded-HostOriginal Host header value
X-Forwarded-PortOriginal port
ForwardedStandard RFC 7239 header combining all of the above

Without processing these headers, request.getRemoteAddr() returns the proxy's IP, request.getScheme() returns http even when the client connected over TLS, and redirect URLs point to incorrect origins.

How NATIVE Works

Setting server.forward-headers-strategy=NATIVE delegates header processing to the embedded servlet container itself. For Tomcat, this activates the RemoteIpValve. For Jetty, it enables the ForwardedRequestCustomizer. For Undertow, it uses the built-in proxy-peer-address handler.

properties
# application.properties
server.forward-headers-strategy=NATIVE

With Tomcat, this is roughly equivalent to manually registering the valve:

java
1@Bean
2public TomcatServletWebServerFactory tomcatFactory() {
3    TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
4    factory.addContextValves(new RemoteIpValve());
5    return factory;
6}

When NATIVE is active, the container rewrites the servlet request object before it reaches any Spring filters or controllers. By the time HttpServletRequest.getRemoteAddr() is called, it already reflects the real client IP.

When NATIVE Is the Right Choice

Use NATIVE when your embedded container has solid built-in support for forward headers and you do not need any special processing logic. This is the typical choice for Tomcat-based applications deployed behind a single well-behaved reverse proxy. The container-level processing happens earlier in the request pipeline, which means all servlet filters see the corrected values from the start.

How FRAMEWORK Works

Setting server.forward-headers-strategy=FRAMEWORK tells Spring to handle the headers itself using a ForwardedHeaderFilter that Spring Boot registers automatically. This filter processes the Forwarded and X-Forwarded-* headers at the Spring filter chain level, regardless of which servlet container is running underneath.

properties
# application.properties
server.forward-headers-strategy=FRAMEWORK

Under the hood, Spring Boot adds a ForwardedHeaderFilter bean:

java
1@Bean
2@ConditionalOnProperty(
3    name = "server.forward-headers-strategy",
4    havingValue = "FRAMEWORK"
5)
6public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
7    ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
8    FilterRegistrationBean<ForwardedHeaderFilter> registration =
9        new FilterRegistrationBean<>(filter);
10    registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
11    return registration;
12}

The ForwardedHeaderFilter wraps the incoming HttpServletRequest and overrides methods like getScheme(), getServerName(), getServerPort(), and getRemoteAddr() with the values extracted from the forwarded headers.

When FRAMEWORK Is the Right Choice

Use FRAMEWORK when you need consistent behavior across different embedded containers, when your container does not support forward headers natively (rare, but possible with custom setups), or when you want fine-grained control at the Spring level. It is also the safer default for reactive (WebFlux) applications, because reactive stacks do not have the same servlet valve concept.

Side-by-Side Comparison

AspectNATIVEFRAMEWORK
Processing layerServlet container (valve/customizer)Spring filter chain
Supported containersTomcat, Jetty, UndertowAny (container-agnostic)
Reactive (WebFlux) supportNot applicableSupported
Header processing timingBefore servlet filtersWithin the Spring filter chain
Configuration scopeContainer-specific tuning availableSpring filter configuration
PortabilityTied to container capabilitiesConsistent across containers
PerformanceMarginally faster (fewer wrappers)Negligible overhead in practice

Configuration with WebFlux

For reactive applications using Spring WebFlux, NATIVE is not available because there is no servlet container. Use FRAMEWORK instead, which registers a ForwardedHeaderTransformer:

properties
# application.properties for WebFlux
server.forward-headers-strategy=FRAMEWORK
java
1// Spring Boot auto-configures this, but you can customize it
2@Bean
3public ForwardedHeaderTransformer forwardedHeaderTransformer() {
4    ForwardedHeaderTransformer transformer = new ForwardedHeaderTransformer();
5    transformer.setRemoveOnly(false);
6    return transformer;
7}

Security Considerations

Forward headers are trivially spoofable. If your application is directly exposed to the internet without a proxy, a malicious client can send X-Forwarded-For: 10.0.0.1 and impersonate an internal address. Spring provides server.tomcat.remoteip.trusted-proxies (for Tomcat NATIVE) and you should configure trusted proxy ranges to prevent header injection.

properties
# Restrict which proxies are trusted
server.tomcat.remoteip.internal-proxies=10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}

For the FRAMEWORK strategy, the ForwardedHeaderFilter processes all requests equally, so place it behind a firewall or configure your infrastructure to strip incoming forwarded headers at the edge before the proxy adds its own.

Cloud Platform Defaults

When deploying to cloud platforms, Spring Boot has built-in detection. On Cloud Foundry and Kubernetes, Spring Boot sets server.forward-headers-strategy=NATIVE by default. If you are deploying behind AWS ALB or another load balancer that injects X-Forwarded-* headers, set the strategy explicitly in your configuration rather than relying on auto-detection.

yaml
# application.yml
server:
  forward-headers-strategy: FRAMEWORK

Common Pitfalls

Setting NATIVE when running a WebFlux application has no effect because there is no servlet container to process the headers. The forwarded headers are silently ignored, and request.getURI() returns the proxy's URL instead of the client's.

Using both NATIVE and a manually registered ForwardedHeaderFilter at the same time causes double processing. The headers get interpreted twice, which can produce incorrect host values or strip headers that should have been preserved.

Forgetting to set the property at all when behind a proxy is the most common mistake. The default value is NONE, which means Spring ignores forwarded headers entirely. This results in HTTP redirect loops when your proxy terminates TLS and the application generates http:// redirect URLs that the proxy upgrades back to HTTPS.

Trusting forwarded headers from untrusted sources is a security risk. Always restrict trusted proxy addresses in production, especially when using the NATIVE strategy with Tomcat.

Not testing with the actual proxy configuration during development leads to surprises in production. Run your local environment behind a simple Nginx reverse proxy to catch header-processing issues early.

Summary

  • NATIVE delegates header processing to the embedded servlet container (Tomcat's RemoteIpValve, Jetty's ForwardedRequestCustomizer).
  • FRAMEWORK uses Spring's own ForwardedHeaderFilter, which works consistently across all containers and is the only option for WebFlux.
  • The default value is NONE, meaning forwarded headers are ignored unless you explicitly enable a strategy.
  • Always configure trusted proxy ranges to prevent header spoofing in production.
  • For most servlet-based applications behind a single reverse proxy, either strategy works. Choose FRAMEWORK when you need container-agnostic behavior or reactive support.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.