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

See also

Last updated: August 11, 2026