Replacing the F5 X-Forwarded-For ISAPI filter on IIS 10

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.

What did the F5 X-Forwarded-For ISAPI filter do?

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.

Which component do you actually have?

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.

Why did it stop working?

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.

What the record says about IIS 10

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.

The problem that survives whichever way that goes

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.

How do I tell whether the old filter is still installed?

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.

What it looks like when it fails

Rather than one clean error, the failure tends to present as one of these:

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.

What your options actually are

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.

Migrating

  1. Remove the old filter from the IIS server (both the ISAPI filter registration and the module entry, if both were added). Recycle the application pool afterwards.
  2. Confirm the BIG-IP is still inserting the header. The proxy side is unchanged by any of this: Insert X-Forwarded-For on the HTTP profile attached to the virtual server. See the F5 BIG-IP guide for the detail.
  3. Install X-Forwarded-For for IIS on each web server.
  4. Add the BIG-IP's SNAT addresses to the Proxy Trust List. This is the part the old filter didn't do, and it's what stops a client forging the header. (See the Installation & Configuration Guide for the format.)
  5. Run 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.

Frequently asked questions

Does F5XFFHttpModule work on Windows Server 2019 or 2022?

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.

Is the F5 filter safe to use if I can get it running?

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.

Is there an official F5 replacement?

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.

Can I just use the IIS custom log field instead?

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.

Will I need to change my log parsing after migrating?

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.

Where can I download F5XFFHttpModule?

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.

How do I know if the F5 ISAPI filter is installed on my server?

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.

The filter is registered but c-ip still shows the load balancer. Why?

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.

Do I need to reconfigure the BIG-IP when I replace the filter?

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.

A supported replacement for the F5 filter

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.

View the product   or request a download →