Forwarded

When an HTTP request passes through proxies and gateways, the origin server loses sight of the original client. The HTTP Forwarded request header preserves client and intermediary details across each hop in the chain.

Usage

When an HTTP request travels through forward proxies, reverse proxies, load balancers, or content delivery networks, the origin server only sees the IP address of the last intermediary. The Forwarded header solves this by carrying the original client details and each hop along the path.

Each intermediary appends or modifies the Forwarded field before passing the request along. The header uses a structured parameter format with four defined parameters: for, by, host, and proto. Multiple hops appear as comma-separated entries.

This header is the standardized replacement for the older X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto headers. While those unofficial headers carry a single piece of information each, the Forwarded header consolidates all proxy-related metadata into one field.

Directives

for

The for parameter identifies the client or the node making the request to the proxy. The value is typically an IP address, but the specification also allows obfuscated identifiers (prefixed with an underscore) and the token unknown.

IPv6 addresses are enclosed in quotes and square brackets. An optional port number follows the address, separated by a colon.

Forwarded: for=192.0.2.60
Forwarded: for="192.0.2.60:47011"
Forwarded: for="[2001:db8::cafe]"
Forwarded: for="[2001:db8::cafe]:4711"
Forwarded: for=unknown
Forwarded: for=_hidden

by

The by parameter identifies the interface where the request entered the proxy. The value format matches for and accepts IP addresses, obfuscated identifiers, or unknown.

Forwarded: for=192.0.2.60;by=203.0.113.43

host

The host parameter carries the original value of the Host header field as received by the proxy. This is useful when a reverse proxy rewrites the Host header before forwarding the request to the origin server.

Forwarded: for=192.0.2.60;host=example.re

proto

The proto parameter records the protocol the client used to connect to the proxy. The value is typically http or https. Load balancers performing TLS termination use this parameter to inform the backend about the original HTTPS connection.

Forwarded: for=192.0.2.60;proto=https

Example

A request passing through two proxies collects information from each hop. The first entry identifies the original client and the protocol used. The second entry records the address of the first proxy as seen by the second.

Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43, for=203.0.113.43;by=198.51.100.17

A single proxy preserving the original host name and protocol alongside the client address produces a combined entry.

Forwarded: for=198.51.100.22;host=shop.example.re;proto=https

When a proxy wants to obscure internal topology, obfuscated identifiers replace real addresses.

Forwarded: for=_client123;by=_proxy456;proto=https

Trusting the chain

Any client sets Forwarded on an outbound request, so the header arriving at an application carries no guarantee about the addresses inside. A request sent directly to an origin with a fabricated for= parameter looks identical to one written by a legitimate proxy. Treating the value as the client address hands attackers control over rate limiting, geolocation, audit logs, and any access rule keyed to an IP address.

Trust runs from the right. Each proxy appends its own element, so the rightmost entry comes from the hop nearest the application and the leftmost is the furthest away and least trustworthy. An application behind a single known proxy reads the element appended by the nearest hop and discards the rest. Counting hops from the left, or reading the first element, trusts whatever the client supplied.

Vendor headers carrying a single address solve the problem at the edge. Cloudflare appends the connecting peer to X-Forwarded-For like any other proxy, and separately publishes the address of the client connecting to Cloudflare in CF-Connecting-IP, while AWS Application Load Balancers append the connection address as the rightmost entry. Reading the vendor-specific header removes the parsing question entirely.

Adoption sits well behind the X-Forwarded-For family despite Forwarded being the standardized replacement. Both families arrive in production as a result, sometimes describing the same hop twice, so applications reconciling them settle on one source of truth rather than merging.

See also

Last updated: August 17, 2026