X-Real-IP
Preserving the original client IP address through a reverse proxy is the function of the X-Real-IP unofficial request header, which carries a single address set by the proxy before forwarding.
Note
The "X-" naming convention for HTTP headers, "X" referring to "experimental", has been deprecated and needs to be transitioned to the formal naming convention for HTTP headers.
Usage
The X-Real-IP header carries a single IP address representing the original client. Reverse proxies set this header before forwarding the request to backend servers. The backend reads X-Real-IP to identify the client instead of using the TCP connection address, which belongs to the proxy.
The header is closely tied to Nginx. Proxies set it
with the proxy_set_header directive, and the
ngx_http_realip_module consumes it on the receiving
side: real_ip_header defaults to X-Real-IP and
names the header whose value replaces the client
address. A typical Nginx proxy configuration sets both
X-Real-IP and
X-Forwarded-For:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
The key difference between X-Real-IP and X-Forwarded-For is the number of addresses. X-Real-IP carries a single IP address, typically the original client. X-Forwarded-For carries a comma-separated list of all addresses in the proxy chain, from the client through each intermediary. In single-proxy architectures the values are identical. In multi-proxy chains, X-Forwarded-For accumulates the full chain, while each proxy that sets X-Real-IP overwrites the value with the address of the previous hop. The original client address survives only when the chain is configured to preserve it, for example by applying the nginx realip module at each hop.
The standardized Forwarded header replaces both X-Real-IP and X-Forwarded-For with a structured format. Adoption of the standard header remains gradual, and many applications continue to rely on X-Real-IP and X-Forwarded-For.
Note
The X-Real-IP header is set by infrastructure
and trusted only when the request arrives from a
known proxy. Clients sending requests directly to
the backend are able to set any value in this
header. Backend applications relying on
X-Real-IP for access control, rate limiting,
or logging need to verify the request originates
from a trusted proxy address. Nginx's
set_real_ip_from directive restricts which
upstream addresses are trusted to provide the
real client IP.
Values
IP address
A single IPv4 or IPv6 address. The value contains no
port number and no additional metadata. Common formats
include 203.0.113.50 for IPv4 and
2001:db8::1 for IPv6.
Example
A reverse proxy forwards the original client IPv4 address. The backend application reads X-Real-IP instead of the TCP source address to identify the client.
X-Real-IP: 203.0.113.50
An IPv6 client address forwarded through a proxy.
X-Real-IP: 2001:db8::1
A complete set of proxy headers forwarded by Nginx. X-Real-IP carries the single client address while X-Forwarded-For preserves the full proxy chain.
X-Real-IP: 203.0.113.50
X-Forwarded-For: 203.0.113.50, 198.51.100.178
X-Forwarded-Proto: https