
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Configuring URL Rewrite and ARR on IIS correctly transforms a standard Windows Server into a capable reverse proxy and application gateway. Many teams struggle because they treat these modules as simple redirect tools rather than integrated infrastructure components that handle traffic routing, SSL termination, and backend health monitoring. This guide provides the exact configuration patterns, security hardening steps, and troubleshooting workflows needed to run this stack reliably in production environments.
How do you install and configure URL Rewrite and ARR on IIS?
Before writing a single rule, you must ensure the foundation is solid. A common mistake in URL Rewrite and ARR on IIS deployments is installing the modules but failing to enable the proxy feature at the server level, which causes all reverse proxy rules to silently fail. Unlike Nginx or Apache where proxying is often default behavior, IIS requires explicit opt-in. For teams managing PowerShell automation for Windows Servers, this setup can be fully scripted to ensure consistency across staging and production.
- Open the Web Platform Installer (WebPI) or use Chocolatey:
cinst iis-arr iis-url-rewrite. - Restart IIS after installation:
iisreset /restart. - Open IIS Manager > Select the Server Node > Application Request Routing Cache.
- In the Actions pane, click Server Proxy Settings.
- Check Enable proxy. Set Time-out to 30 seconds (default) and adjust based on your slowest backend API call.
- Click Apply. This step is mandatory; without it, rewrite rules with
type="Rewrite"targeting external ports will return 404 or 500 errors.
Once enabled, verify the installation by checking the %windir%\system32\inetsrv\config\applicationHost.config file for the <proxy enabled="true" /> element under system.webServer/proxy. If you are deploying to a fresh server, combine this with initial server setup practices adapted for Windows, ensuring firewall rules only expose port 443 publicly while keeping backend ports restricted to localhost or private VLANs.
How do you write effective URL Rewrite rules for reverse proxying?
The syntax of URL Rewrite and ARR on IIS relies on XML-based rules in web.config. While the GUI helps generate basic patterns, production configurations require manual tuning for performance and correctness. A frequent pitfall is using regular expressions when wildcard or exact matches suffice; regex evaluation adds CPU overhead on every request. Always prefer matchType="ExactMatch" or Wildcard unless pattern capture is genuinely required.
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxy-API" stopProcessing="true">
<match url="^api/(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://localhost:5000/api/{R:1}" />
</rule>
<rule name="Force-HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer> In the example above, note the use of {C:1} to preserve the original protocol scheme during proxying. Hardcoding http:// in the action URL breaks WebSocket upgrades and secure cookie flags. Also critical is stopProcessing="true"; without it, subsequent rules may re-process an already-proxied request, causing loops or unintended redirects. When debugging complex routing logic, refer to structured logging best practices to capture rewrite decisions without flooding disk I/O.
Handling Headers and Host Preservation
Backends often need the original host header for virtual hosting or generating correct absolute URLs. By default, ARR forwards the request with the backend's hostname. To preserve the original client-facing host:
- Navigate to IIS Manager > Server Node > ARR > Server Proxy Settings.
- Uncheck "Reverse rewrite host in response headers" if you want the backend's raw response, OR keep it checked to mask backend topology.
- Add a custom server variable
HTTP_X_ORIGINAL_HOSTin the rewrite rule to pass the true host explicitly, allowing .NET Core or Node apps to reconstruct URLs safely behind the proxy.
How does ARR handle load balancing and health checks?
Beyond simple proxying, URL Rewrite and ARR on IIS functions as a Layer 7 load balancer. Unlike hardware appliances, ARR integrates directly with the IIS worker process, sharing the same memory space and event logs. This tight coupling simplifies observability but means a misconfigured health check can take down your entire frontend. Health probes should always target a lightweight endpoint (e.g., /health) that returns 200 OK without database dependencies.
| Algorithm | Best For | Caveat |
|---|---|---|
| Round Robin | Stateless APIs with uniform processing time | Ignores actual server load; can overwhelm slow nodes |
| Least Requests | Mixed workload with variable query complexity | Slight overhead tracking active connections per node |
| Response Time | Heterogeneous backend hardware | Can cause flapping during transient network blips |
| Client IP Hash | Session affinity without shared state | Breaks if clients sit behind NAT/proxy pools |
Configure health checks via the UI or directly in applicationHost.config. Set the failure threshold to 3 and recovery threshold to 1 to avoid premature failover during garbage collection pauses. For .NET applications, align your health endpoint with the ASP.NET Core Health Checks middleware to ensure ARR sees the same status your orchestrator would.
How do you troubleshoot common URL Rewrite and ARR failures?
When URL Rewrite and ARR on IIS fails, the error messages are notoriously vague. A 502 Bad Gateway usually means ARR couldn't connect to the backend, while a 500.52 often indicates a rewrite rule syntax error. Enable Failed Request Tracing (FREB) specifically for the rewrite module; standard IIS logs won't show rule evaluation details. Add a tracing rule for status codes 400-599 and inspect the REWRITE_MODULE events to see exactly which condition failed.
Another silent killer is the response buffer limit. By default, ARR buffers entire responses before sending to the client. Large file downloads or streaming SSE endpoints will timeout or consume excessive RAM. Disable buffering for specific paths using:
<system.webServer>
<proxy enabled="true" bufferResponse="false" />
</system.webServer> Apply this selectively at the site or folder level, not globally, to maintain caching benefits for static assets. If you're integrating with modern observability stacks, correlate FREB traces with data from Prometheus and Grafana monitoring setups to distinguish between IIS-layer failures and backend application latency.
SSL Offloading and Certificate Management
Terminate TLS at the IIS edge. Backends should communicate over HTTP within the trusted network to reduce encryption overhead. However, some applications require knowing the original protocol. Always set the X-Forwarded-Proto header in your rewrite rules:
<serverVariables>
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
</serverVariables> Without this, OAuth callbacks and secure cookie generation will fail silently. Ensure your certificate binding uses SNI for multi-tenant hosting, and automate renewal via ACME clients compatible with IIS to prevent expiration outages.
Optimizing URL Rewrite and ARR on IIS for Production
Running URL Rewrite and ARR on IIS in production demands more than functional correctness; it requires performance tuning and security hardening. Disable kernel-mode caching for proxied content unless your backends are completely stateless and cache-friendly. Kernel cache bypasses the user-mode rewrite engine, meaning dynamic routing rules won't execute for cached responses. Test thoroughly before enabling.
Implement request filtering at the ARR layer to block malicious payloads before they reach backend apps. Define max query string length, max URL length, and disallowed extensions in requestFiltering. This acts as a first line of defense complementing your WAF. Monitor ARR-specific performance counters (Current Requests, Failed Requests/sec) to establish baselines. Spikes in failed requests often indicate backend health check misconfiguration rather than actual traffic issues.
Finally, document your configuration as code. Export your web.config and applicationHost.config sections into version control. Manual changes via IIS Manager drift quickly in team environments. Use PowerShell DSC or Ansible to enforce desired state, ensuring every disaster recovery rebuild matches production exactly. This discipline separates fragile setups from resilient infrastructure.
Next Steps for Your IIS Infrastructure
Mastering URL Rewrite and ARR on IIS gives you a powerful, native Windows alternative to external load balancers for many scenarios. Start with the installation verification steps above, implement health-checked server farms before going live, and instrument failed request tracing early. If your architecture is growing beyond what a single Windows edge can handle, consider hybrid approaches or migration paths discussed in our Nginx vs Apache performance comparison. Ready to audit your current IIS setup or design a compliant reverse proxy layer? Contact me to discuss your infrastructure requirements.