The F5-published filter served a lot of estates well for a long time. F5 archived it in 2016, before Windows Server 2016 shipped, and it's still the top answer in forum threads a decade later. Here's what it did, why it stopped, and what to move to.
Short answer. F5 published two IIS components on DevCentral: an older ISAPI filter and a newer HTTP module (F5XFFHttpModule) for IIS 7 and later. Both were community tools rather than supported F5 products. F5 put the source on GitHub in October 2015 and archived the repository in May 2016, before Windows Server 2016 shipped, and it has not changed since.
Microsoft's own guidance is that neither component works on IIS 10. Separately, and regardless of whether you can get one running, neither validates the forwarding chain: both read the header and write it to c-ip unconditionally, so anything able to reach IIS directly can put a chosen address into your logs.
It read the X-Forwarded-For header inserted by a BIG-IP and wrote the real client address into the IIS c-ip log field, so IIS logs showed visitors rather than the load balancer without any downstream tooling being reconfigured.
It solved a problem Microsoft still hasn't: IIS logs the address of whoever opened the TCP connection, so behind a BIG-IP applying SNAT, every request in the log carries an F5 address. The filter read the X-Forwarded-For header the BIG-IP inserted and wrote the real client address into the IIS c-ip field, so existing log tooling kept working without being reconfigured.
That approach was, and remains, the correct one. The problem is purely one of maintenance.
Worth settling before anything else, because the two get conflated constantly and they install differently:
| Component | Era | Installed as |
|---|---|---|
| X-Forwarded-For ISAPI filter | The original, IIS 6 and IIS 7 | An ISAPI filter registration. Native code, no configuration. |
HTTP module (F5XFFHttpModule) |
Later, written for IIS 7 once Microsoft steered people away from ISAPI filters | A module entry. Reads an optional F5XFFHttpModule.ini beside the DLL. |
F5XFFHttpModule is the name of the HTTP module specifically. It is not another name for the ISAPI filter, though it is frequently used as one.
Because it stopped being maintained before the platform it needed to support arrived. Both components were community tools published on F5 DevCentral, not supported F5 products, shared for the benefit of customers running IIS behind a BIG-IP.
F5 put the source on GitHub in October 2015 and archived that repository in May 2016. Windows Server 2016, which is what ships IIS 10, was not generally available until later that year. The code was therefore set aside before the server release most people now need it for, and it has not changed since.
Because neither was a product, there's no support channel, no compatibility statement and no newer build. The DevCentral articles and the Stack Overflow answers pointing at them are still there and still rank well, which is why administrators keep finding them, deploying onto Windows Server 2019 or 2022, and discovering the hard way that they aren't viable.
Rather than ask you to take our word for it, here are the sources:
The honest summary: Microsoft says it does not work, there is at least one report of it taking an application pool down, and there is one person who says they got something working. What none of that changes is the next section.
Neither component validates anything. Both simply read the header and write it into the log. The published source contains no trust list, no allow-list, no notion of a known proxy, and no chain validation of any kind, in either the ISAPI filter or the HTTP module.
That matters more than the compatibility question. X-Forwarded-For is a client-supplied header. If anything can reach your IIS server directly, bypassing the BIG-IP, it can set that header to any value it likes and the filter will write it into c-ip as fact. A forged entry then sits in your audit trail indistinguishable from a real one.
An audit trail that is confidently wrong is a worse position than one that is visibly wrong. A log full of load balancer addresses is obviously unhelpful and everyone knows to work around it. A log full of plausible-looking client addresses, some of which were invented by whoever sent the request, is trusted, and that trust is misplaced. This is why any replacement worth deploying validates the chain against proxies you have explicitly named.
A note on fairness to F5. Nothing here is a criticism of F5 or of the engineers who wrote these. Publishing the source and then archiving it is exactly the right thing to do with a community tool you no longer maintain: it is a clear public signal, and it leaves the code available to anyone who wants to fork it. The issue is that search engines still surface the original articles as the answer, so people adopt an archived component for a production estate without realising its status.
Check the ISAPI filter list and the module list, because depending on how it was deployed it may appear in either or both. From an elevated prompt on the web server:
cd %windir%\system32\inetsrv
appcmd list config /section:isapiFilters
appcmd list modules
In IIS Manager the same information is under ISAPI Filters at server and site level, and under Modules. You're looking for an entry pointing at a DLL somewhere like C:\Windows\System32\inetsrv\ or a folder named after the filter. Checking the DLL's file version and date is usually faster than trying to recognise the name, because the name varies by how each estate deployed it. An accompanying F5XFFHttpModule.ini beside the DLL identifies the HTTP module specifically.
Rather than one clean error, the failure tends to present as one of these:
c-ip still shows the BIG-IP on every request. This is the most common outcome and the most confusing, because there is nothing in the event log to look at.False, which is the default, an old 32-bit filter is simply never loaded.The second point catches people who flip Enable 32-Bit Applications to True to make the filter load, and then find they have changed the bitness of every application in that pool to accommodate an abandoned component. That is a trade worth avoiding.
| Option | Status | The problem |
|---|---|---|
| Keep the F5 filter or HTTP module | Archived | Source archived by F5 in 2016 and unchanged since. Microsoft's guidance is that it does not work on IIS 10. No support channel and no newer build, because both were community tools rather than products. Critically, neither validates the forwarding chain, so a forged header is logged as fact. |
| IIS 8.5+ custom log field | Supported | Adds X-Forwarded-For as an extra column; it does not replace c-ip. Every SIEM connector, geo-IP lookup and compliance parser reading c-ip still sees the BIG-IP. It also has no trust list, so a spoofed header is logged as-is. |
| IIS Advanced Logging | Discontinued | Wrote to a separate log file, bypassing the standard W3C log. Discontinued by Microsoft and no longer available. |
| Write your own HTTP module | DIY | Viable, but you now own the chain-walking logic, the trust-list validation, the IPv6 edge cases, and the maintenance, for every Windows Server upgrade, indefinitely. |
| Winfrasoft X-Forwarded-For for IIS | Supported | Commercially supported, built for IIS 10 on Windows Server 2016–2025. Replaces c-ip directly and validates the chain against a Proxy Trust List. |
IISRESET and confirm c-ip shows real client addresses.Because both approaches write to the same field, nothing downstream changes. Your SIEM, log shipper and reporting continue reading c-ip exactly as they did when the old filter was working.
Microsoft's guidance is that it does not. A Microsoft responder on Microsoft Q&A states that neither F5XFFHttpModule nor the IIS 7 Advanced Logging module works on IIS 10, which is what ships with Windows Server 2016 and later. It was written for IIS 7, and F5 archived the source in May 2016 before Windows Server 2016 was generally available. There is no updated build, because it was a community tool rather than a supported F5 product.
Not on a server reachable outside your proxy. Neither component validates the forwarding chain: the published source contains no trust list and no notion of a known proxy, so whatever arrives in the header is written straight into c-ip. Anything able to connect to IIS directly can therefore choose what address appears in your logs, and a forged entry is indistinguishable from a genuine one afterwards.
No. F5's side of the configuration (Insert X-Forwarded-For on the HTTP profile) is fully supported and unchanged; that inserts the header. What was never a supported product is the IIS-side component that reads the header and writes it into the log. That piece is what needs replacing.
Only if nothing downstream reads c-ip. The custom field adds a new column at the end of the log while c-ip continues to show the BIG-IP, so every tool keyed to the standard field needs reconfiguring, and many SIEM connectors and compliance parsers can't be. It also logs whatever the header contains, with no trust validation.
No. Both the old filter and X-Forwarded-For for IIS write the client address into the same standard c-ip field, so anything already consuming your IIS logs continues to work unchanged.
The DevCentral articles, the Codeshare entry and the source on GitHub are all still reachable, which is precisely the problem: that repository is archived and unchanged since 2016, and none of it works on IIS 10. There is no newer build to look for. If you need the code to fork rather than to deploy, GitHub is the right place to get it.
Run appcmd list config /section:isapiFilters and appcmd list modules from %windir%\system32\inetsrv, or check ISAPI Filters and Modules in IIS Manager. Check the DLL's file version and date rather than trying to recognise the name, which varies between estates. An F5XFFHttpModule.ini beside the DLL points to the HTTP module rather than the older ISAPI filter.
Usually one of two things. Either the filter is not loading at all, which happens when a 32-bit build meets a 64-bit application pool, or it is loading and simply not functioning on IIS 10. Neither writes anything useful to the event log, which is why the failure is so often mistaken for a proxy misconfiguration.
No. The F5 side is unchanged and fully supported: Insert X-Forwarded-For on the HTTP profile attached to the virtual server. Only the IIS-side component that reads the header is being replaced. Worth confirming the setting is still enabled while you are in there.
X-Forwarded-For for IIS does what the DevCentral filter did: writes the real client address into the standard c-ip field, with a Proxy Trust List, commercial support, and builds for IIS 10 on Windows Server 2016–2025. Free 14-day trial.