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.
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:
| Header | Purpose |
X-Forwarded-For | Original client IP address |
X-Forwarded-Proto | Original protocol (http or https) |
X-Forwarded-Host | Original Host header value |
X-Forwarded-Port | Original port |
Forwarded | Standard 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.
With Tomcat, this is roughly equivalent to manually registering the valve:
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.
Under the hood, Spring Boot adds a ForwardedHeaderFilter bean:
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
| Aspect | NATIVE | FRAMEWORK |
| Processing layer | Servlet container (valve/customizer) | Spring filter chain |
| Supported containers | Tomcat, Jetty, Undertow | Any (container-agnostic) |
| Reactive (WebFlux) support | Not applicable | Supported |
| Header processing timing | Before servlet filters | Within the Spring filter chain |
| Configuration scope | Container-specific tuning available | Spring filter configuration |
| Portability | Tied to container capabilities | Consistent across containers |
| Performance | Marginally 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:
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.
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.
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
NATIVEdelegates header processing to the embedded servlet container (Tomcat'sRemoteIpValve, Jetty'sForwardedRequestCustomizer).FRAMEWORKuses Spring's ownForwardedHeaderFilter, 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
FRAMEWORKwhen you need container-agnostic behavior or reactive support.
Related reading
- Spring spring.profiles.include overrides
- Spring Test returning 401 for unsecured URLs
- Spring Transaction method call by the method within the same class, does not work?
- Spring @Transactional - isolation, propagation
- Spring Web MVC 4 with Java 8 best way to make chained DeferredResult callbacks in the service layer?
- Spring WebFlux - ServerResponse Jackson Serializer problems
- Spring Webflux JPA Reactive Repositories are not supported by JPA
- Spring Webflux vs Vert.x

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack 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.