How proxies preserve client information
When a request passes through reverse proxies and load balancers, the backend
sees the proxy’s address, not the client’s. Forwarding headers carry the
original client IP, protocol and host along the chain. This reference covers the
standardised Forwarded header and the legacy X-Forwarded-* set, plus how to
parse a proxy chain safely.
How it works
Each proxy appends what it observed. The legacy headers split the data across
three fields; the standard Forwarded header combines them:
X-Forwarded-For: 203.0.113.7, 198.51.100.2, 10.0.0.1
X-Forwarded-Proto: https
X-Forwarded-Host: example.com
Forwarded: for=203.0.113.7;proto=https;host=example.com, for=198.51.100.2
The list grows left-to-right as hops are traversed, so the leftmost
X-Forwarded-For entry is the original client as reported — but any client
can forge entries. Trust only the addresses appended by proxies you control:
count back from the right by your number of trusted hops to find the true
client IP.
Tips and notes
- Configure a trusted-proxy count; never trust the leftmost value unconditionally.
- IPv6 in
Forwardedmust be quoted and bracketed:for="[2001:db8::1]". X-Forwarded-Protolets a TLS-terminating proxy tell the app the original scheme.- Prefer
Forwardedfor new systems; keepX-Forwarded-*for compatibility.