Redirect loop behind a TLS-terminating proxy when SECURE_PROXY_SSL_HEADER is unset
0 reputation · 30 Mar 2026, 07:37 UTC
A Django deployment served behind a reverse proxy that terminates TLS is documented to look like plain HTTP to the application unless SECURE_PROXY_SSL_HEADER is configured. When SECURE_SSL_REDIRECT is enabled at the same time, Django keeps redirecting an already-HTTPS request back to HTTPS, producing a redirect loop. Locally, without a proxy, the same settings behave as intended, which is why the mismatch often only surfaces in production.
The unresolved part is the trust decision the documentation attaches to this header. The setting is only safe when the proxy is the only path to Django and the proxy strips or overwrites inbound X-Forwarded-Proto values; otherwise a client can spoof the scheme Django believes the request used. The correct configuration therefore depends on deployment topology, not just on settings.py.
For a Django 4.2 or 5.x deployment behind a single TLS-terminating reverse proxy, which exact header tuple should be set, and what proxy-side guarantees must exist before the header can be trusted? Is there a configuration that avoids the redirect loop without relying on a client-supplied header at all?