Practical, vendor-specific guides for logging the real client IP address in Microsoft IIS behind proxies, load balancers and CDNs, using the X-Forwarded-For header.
Short answer. If IIS sits behind a proxy, load balancer or CDN, the c-ip field in your logs records that device, not your visitor, because c-ip is filled from the TCP connection and the only connection IIS sees is the one from the proxy. The visitor's address does arrive, in the X-Forwarded-For request header, but IIS has never read that header natively. Closing the gap means getting the header value into the c-ip field, and trusting only the proxy that set it. The guides below cover that for each vendor, and X-Forwarded-For and IIS covers the header itself if you want the background first.
Start from whatever sits in front of IIS. The mechanism is the same everywhere, but the header name and the addresses you have to trust are not.
| In front of IIS | Header carrying the client IP | Guide |
|---|---|---|
| Cloudflare | CF-Connecting-IP, and X-Forwarded-For | IIS behind Cloudflare |
| F5 BIG-IP | X-Forwarded-For (once the HTTP profile inserts it) | IIS behind F5 BIG-IP |
| AWS ALB, ELB or CloudFront | X-Forwarded-For | IIS behind an AWS load balancer |
| Azure App Gateway or Front Door | X-Forwarded-For, plus X-Azure-ClientIP and X-Azure-SocketIP | IIS behind Azure |
| Nginx or HAProxy | X-Forwarded-For (you configure it) | IIS behind Nginx or HAProxy |
| IIS ARR | X-Forwarded-For, plus X-ARR-LOG-ID | IIS behind ARR |
| Barracuda WAF or Load Balancer ADC | X-Forwarded-For (inserted by default in proxy mode) | IIS behind Barracuda |
| Akamai | X-Forwarded-For, plus True-Client-IP if enabled | IIS behind Akamai |
| Something else, or you are not sure | Compare them side by side | Proxy client IP header reference |
Running a specific application rather than a plain site? See Exchange behind a load balancer, SharePoint behind a reverse proxy, or ASP.NET Core UseForwardedHeaders. Replacing the retired F5 component is covered in replacing the F5 ISAPI filter on IIS 10, and if this is a logging and audit requirement rather than an analytics one, start with IIS client IP for SIEM and compliance. Already added a custom log field and found it empty? See IIS custom field for X-Forwarded-For not working.
The header is a comma-separated chain, and each proxy appends the address it received the connection from. That makes the leftmost entry the one furthest from you, and the one entirely under the caller's control: anyone can send an X-Forwarded-For header containing any address they like before your proxy ever sees the request. The reliable value is found by reading the chain from the right and stopping at the first address that is not a proxy you trust. That is what a Proxy Trust List is for, and it is why "just log the header" is not a safe answer on its own. The header reference works through the ordering in detail, and how to log X-Forwarded-For in IIS covers what the native IIS custom log field does and does not solve.
No guides match that search. Try a different term, or get in touch. X-Forwarded-For for IIS works behind any proxy, load balancer or CDN, whether or not there's a guide for it yet.
What the header contains and why the leftmost address is the wrong one, whether IIS supports it natively (it does not, in any version), what the IIS 8.5 custom log field does and does not solve, and which of the three things people mean by this question you are actually asking.
Read the guide →A table of the client IP headers set by Cloudflare, AWS, Azure, F5, ARR, Nginx, HAProxy, Akamai and Fastly, which are on by default, how the X-Forwarded-For chain is ordered, and why the leftmost address isn't the one to trust.
Read the reference →Adding an X-Forwarded-For column on IIS 8.5 and later, server-wide with PowerShell, and why the Advanced Logging route for IIS 7 to 8 is now closed. Then why that column leaves c-ip still showing your proxy, and what to do about it.
Read the reference →You added the field and the column is missing, empty or all dashes. The eight causes, starting with the one nobody expects: IIS quietly starts writing a second log file with _x on the end, and your data is in that one. Plus why Add Field is greyed out, and the Source Type that silently matches nothing.
The questions we're asked most often: the c-ip field versus a custom log column, replacing the old F5 ISAPI filter on IIS 10, and Exchange behind a load balancer.
Read the FAQ →F5 archived its DevCentral ISAPI filter and F5XFFHttpModule HTTP module in 2016. Which component you have, what Microsoft says about IIS 10, why neither validates the forwarding chain, and how to migrate without changing anything downstream.
Read the guide →Why SIEM connectors, geo-IP lookups and compliance parsers all key off the standard c-ip field, why an extra log column doesn't satisfy them, and why an unvalidated header weakens an audit trail.
Read the guide →On-premises Exchange published through an F5, NetScaler or Azure Application Gateway logs the balancer's address for OWA and ActiveSync. Fixing the IIS audit trail, and the free native fix for IP Address and Domain Restrictions.
Read the guide →Multi-WFE SharePoint farms published through a load balancer log the proxy's address, not the visitor. Getting the real client IP into the IIS c-ip field farm-wide, and what this does and doesn't cover.
Read the guide →Neither proxy forwards the client IP unless you configure it to. The one directive each needs: proxy_set_header in Nginx, option forwardfor in HAProxy, and how to get the address into your IIS logs once it arrives.
Read the guide →Configuring ForwardedHeadersOptions properly: middleware order, KnownProxies, ForwardLimit, why it silently does nothing in production, and where it stops short of fixing the IIS log itself.
Read the guide →Behind Cloudflare, IIS logs the edge IP rather than the visitor. How to restore the real client IP in your IIS logs from the X-Forwarded-For header, with a Proxy Trust List and origin lock-down.
Read the guide →Behind an F5 BIG-IP, IIS logs the SNAT address. Enable Insert X-Forwarded-For on the HTTP profile and record the real client IP in your IIS c-ip field.
Read the guide →The Barracuda WAF and Load Balancer ADC send X-Forwarded-For by default in proxy mode. Why Client Impersonation is not free, and why the IIS procedure in Barracuda's own documentation cannot be followed on IIS 10.
Read the guide →Akamai sends X-Forwarded-For by default and True-Client-IP only when somebody enables it. Why the single-value header looks more trustworthy than it is, the toggle that lets clients set it themselves, and which addresses belong in the trust list when you run Site Shield.
Barracuda's IIS instructions begin with a Microsoft extension that no longer exists. What happens at each dead link, how to set up Enhanced Logging properly instead, and the four things it still does not fix.
Read the guide →Behind an AWS ALB or Classic ELB, IIS logs the load balancer's private IP. Use the automatically-added X-Forwarded-For header to log the real visitor in IIS.
Read the guide →Behind Azure Application Gateway or Front Door, IIS logs the Azure service IP. Log the real client IP from X-Forwarded-For and trust the right Azure ranges.
Read the guide →With Application Request Routing as a reverse proxy, backend IIS logs the ARR server IP. Preserve the client IP via X-Forwarded-For and log it on the backend.
Read the guide →Need a setup we haven't covered? X-Forwarded-For for IIS works behind any proxy, load balancer or CDN that sets the X-Forwarded-For header. Get in touch and we'll help with your specific deployment.