Native support for X-Forwarded-For / PROXY Protocol for Client IP Detection

Currently, Plex Media Server strictly relies on the L4/TCP socket source IP to identify client IP addresses on the Dashboard/Now Playing sessions. It completely ignores standard HTTP reverse-proxy headers like X-Forwarded-For and X-Real-IP, as well as HAProxy PROXY Protocol v1/v2 wrappers.

For self-hosted setups that utilize overlay mesh networks or WireGuard tunnels (such as NetBird, Tailscale) with an edge reverse proxy (Traefik, Nginx, Caddy), this presents a significant usability limitation:

  1. Proxy Source IP Masking: Because traffic traverses a tunnel interface before hitting Plex’s TCP socket, the Dashboard constantly reports the internal VPN/tunnel IP (e.g., 100.x.x.x) rather than the true client IP.

  2. Geo/Location Tracking: Stream details on the admin dashboard display the proxy node location instead of the client’s real geographic location/ISP.

Proposed Solution:

Please consider adding a server setting (or dynamic header parser) that allows admins to define trusted proxy CIDRs (e.g., Trusted Proxies: 100.64.0.0/10, 127.0.0.1). When a connection originates from a trusted proxy IP, Plex Media Server should parse the X-Forwarded-For header or accept HAProxy PROXY Protocol to inspect the real client IP for session reporting and geolocation.

This would bring Plex in line with modern web standards used by other media and web servers.

I’m seeing X-Forwarded-For work on Plex Media Server 1.43.5.11029 on Windows, behind nginx.

I tested playback from my Android phone over AT&T cellular. nginx forwards X-Forwarded-For and X-Real-IP, and Plex’s own log explicitly says:

[RequestParser] Using X-Forwarded-For: <phone’s public IPv6 address> as remote address

nginx’s access logs confirm the video requests passed through the proxy. Plex’s session reports that same public IPv6 address, and Tautulli identifies it as AT&T.

So the statement that Plex completely ignores X-Forwarded-For doesn’t match my setup. There may be a version, platform, or proxy configuration difference worth investigating. I haven’t tested HAProxy PROXY protocol support.

Thanks for checking your logs! That log line ([RequestParser] Using X-Forwarded-For...) is super helpful.

Looking closely at the differences, it appears Plex’s RequestParser only trusts and parses X-Forwarded-For when the incoming TCP socket connection originates from a local/private network interface (like 127.0.0.1 or 192.168.x.x on a local Nginx instance).

In setups where the proxy routes traffic over an overlay mesh network / VPN adapter (like NetBird (Traefik), Tailscale, or WireGuard on 100.64.0.0/10), Plex treats the incoming socket IP as an external/untrusted hop and strips/ignores the header.

This confirms that having a configurable “Trusted Proxies” setting (where admins can specify custom CIDRs like 100.64.0.0/10 or container bridges) would fully resolve the issue for overlay and multi-node reverse proxy setups!

for now i think i might have found a way with a local caddy server on the local plex server forwarding from the (in my case netbird ip) back to local IP:

plex.domain.xxx (netbird reverse proxy) set to netbird_machine_plex_ip:8080

:8080 {
reverse_proxy 127.0.0.1:32400 {
header_up Host 127.0.0.1:32400
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
header_up X-Real-IP {http.request.header.X-Real-IP}
}
}

This seems to work, sort of for now.