Super Java Host
  1. Home
  2. Guides
  3. Tomcat behind Nginx

Tomcat behind Nginx: HTTPS and real client IP

A proxy in front of Tomcat hides two facts from your application: that the user came over HTTPS, and who the user is. Both are fixed with headers and one valve.

The symptoms

  • After login the browser is sent to http://yourdomain/... even though you opened https.
  • An infinite redirect loop on pages that require HTTPS.
  • request.getRemoteAddr() and the access log show 127.0.0.1 for every visitor.
  • Generated absolute URLs use port 8080.

Tomcat only sees a plain HTTP connection from Nginx on the same machine. You must tell it the original details.

1. Nginx: send the headers

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Test and reload: sudo nginx -t && sudo systemctl reload nginx.

2. Tomcat: add the RemoteIpValve

In server.xml, inside the <Host> element (next to the AccessLogValve), add:

<Valve className="org.apache.catalina.valves.RemoteIpValve"
       remoteIpHeader="X-Forwarded-For"
       protocolHeader="X-Forwarded-Proto"
       internalProxies="127\.0\.0\.1|::1" />

Restart Tomcat. Now request.isSecure() is true and the scheme is https for requests that came through HTTPS. The access log shows the visitor address if its pattern uses %a. The internalProxies value matters for safety: Tomcat trusts the forwarded headers only from addresses that match it, so a visitor cannot fake them.

3. Spring Boot with embedded Tomcat

You do not edit server.xml. Set this in application.properties (or the environment variable SERVER_FORWARD_HEADERS_STRATEGY=native):

server.forward-headers-strategy=native

Use framework if you need Spring to handle Forwarded headers itself. For most setups native is right.

4. Bind Tomcat to localhost

If everyone goes through Nginx, make sure nobody can reach Tomcat directly and send fake headers. In server.xml add address="127.0.0.1" to the HTTP connector, or block port 8080 in the firewall.

Check

curl -sI https://yourdomain.example/some-page-that-redirects | grep -i location

The Location header must begin with https://.

Questions about tomcat behind nginx

Why is the client IP always 127.0.0.1?

Tomcat sees Nginx as the client. Send X-Forwarded-For from Nginx and add the RemoteIpValve, or set the forward headers strategy in Spring Boot.

Is it safe to trust X-Forwarded-For?

Only from your own proxy. The internalProxies setting makes Tomcat ignore the header from any other address.

Last updated October 29, 2026.

Your own Java server, billed monthly

Plans from €15.30 a month. Set up for you, or run for you.