IIS URL Rewrite: Install, Rules & HTTPS Redirect


Our IIS web server support team configures URL Rewrite on most of the IIS servers it manages, because the two most common requests — force HTTPS and pick one canonical hostname — both go through this module. This page covers installing the module, the structure of a rule, the redirect rules you will actually deploy, reverse proxy with ARR, and the failure modes that follow a bad rule into production.
What the URL Rewrite module is
URL Rewrite is a free extension for IIS. It is not built into Windows Server — a clean IIS install has no rewrite engine, and a web.config containing a rewrite section on such a server produces an immediate 500.19 error. The current version is 2.1, available from the official iis.net download page for IIS 7 through IIS 10, in x86 and x64 builds.
The module does two distinct things, and the distinction matters for every rule you write:
- Rewrite — changes the URL internally on the server. The client never sees the change; the browser address bar keeps the original URL. Used for friendly URLs and reverse proxying.
- Redirect — sends an HTTP response (301, 302, 307) telling the client to request a different URL. The browser address bar changes. Used for HTTPS enforcement and canonical hostnames.
If IIS itself is new to you, start with what IIS is and how it is structured — rules live inside the same configuration hierarchy as everything else in IIS.
Installing URL Rewrite 2.1
The Web Platform Installer, which older guides reference as the install path, was retired by Microsoft (the WebPI product feed was shut down at the end of 2022). Install from the standalone MSI instead:
- Download the x64 MSI (
rewrite_amd64_en-US.msi) from the URL Rewrite download page. Use x86 only on 32-bit servers, which in practice means almost never. - Run the MSI on the server. No configuration choices are presented; it installs the native module and registers it globally.
- Close and reopen IIS Manager. A URL Rewrite icon appears in the Feature View for the server, each site, and each application.
- No reboot is required. An
iisresetis not required either, but running one removes any doubt on a server with long-lived worker processes.
On Azure App Service the module is pre-installed; you deploy only the web.config rules.
Rule anatomy
Per the official rule-writing documentation, every inbound rule has four parts:
| Part | What it does |
|---|---|
| Name | Unique identifier for the rule. IIS Manager refuses duplicate names within a scope. |
| Match URL | A regular expression tested against the URL path (without the leading slash, without hostname or query string). Capture groups in parentheses become back-references: {R:1}, {R:2}. |
| Conditions | Optional additional tests against server variables — {HTTPS}, {HTTP_HOST}, {REQUEST_URI}, {HTTP_USER_AGENT} and so on. Condition capture groups become {C:1}, {C:2}. |
| Action | What happens on match: Rewrite, Redirect, AbortRequest, CustomResponse, or None. |
Rules are stored in web.config under system.webServer/rewrite (site- and application-level rules) or in ApplicationHost.config (server-level rules). A minimal rule looks like this:
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite to article.aspx">
<match url="^article/([0-9]+)/([_0-9a-z-]+)" />
<action type="Rewrite" url="article.aspx?id={R:1}&title={R:2}" />
</rule>
</rules>
</rewrite>
</system.webServer>
Rules run in document order. stopProcessing="true" ends evaluation after a rule matches — set it on every redirect rule, because there is no reason to keep evaluating rules against a request you have already told the client to abandon. The full attribute set is in the configuration reference.
IIS redirect HTTP to HTTPS
This is the rule most servers need. It matches every request, checks that the connection is not already HTTPS via the {HTTPS} server variable, and issues a permanent (301) redirect to the same host and path on HTTPS:
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
Points that get missed:
{HTTPS}is a server variable that is the string OFF for plain HTTP and ON for TLS connections. The pattern match is case-insensitive by default.redirectType="Permanent"emits 301. The default is 301 already, but state it explicitly — a 302 here wastes the ranking signal and browsers will not cache it.- The site still needs an HTTP binding on port 80. The redirect rule runs on the HTTP request; if you remove the port 80 binding, clients get a connection failure instead of a redirect.
- Query strings are preserved automatically because
appendQueryStringdefaults to true on redirect actions. - After the redirect is verified, add an HSTS header so returning browsers skip the HTTP round trip entirely. IIS 10 version 1709 and later support a native
<hsts>element per site.
www vs non-www canonical rule
Pick one hostname and 301 everything else to it. Redirecting non-www to www:
<rule name="Canonical www" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^example.com$" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
For the opposite direction, match ^www.example.com$ and redirect to the bare domain. Two rules of caution: redirect straight to the HTTPS canonical host (as above) so a visitor never chains through two 301s, and place the canonical-host rule after the HTTPS rule with stopProcessing="true" on both so order stays deterministic.
Other common rules
Remove trailing slash:
<rule name="Remove trailing slash" stopProcessing="true">
<match url="(.*)/$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Redirect" url="{R:1}" redirectType="Permanent" />
</rule>
The two negated conditions stop the rule from breaking real directories and files.
Force lowercase URLs:
<rule name="Lowercase" stopProcessing="true">
<match url="[A-Z]" ignoreCase="false" />
<action type="Redirect" url="{ToLower:{URL}}" redirectType="Permanent" />
</rule>
Only apply this to content URLs. It will break case-sensitive query-string tokens and mixed-case static assets referenced by exact name; scope it or add exclusion conditions before deploying.
Block a user-agent:
<rule name="Block scraper" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="BadBotName" />
</conditions>
<action type="AbortRequest" />
</rule>
AbortRequest drops the connection without a response. Use CustomResponse with a 403 if you want the client to see a status code.
Reverse proxy with ARR
URL Rewrite alone rewrites paths within a site. To forward requests to a different server — an app on another port, a backend Node or Kestrel process, an internal application published through IIS — you add Application Request Routing (ARR), which provides the actual proxy engine. The steps, per the official reverse proxy walkthrough:
- Install ARR from its iis.net download page (URL Rewrite must already be installed).
- In IIS Manager, select the server node, open Application Request Routing Cache, click Server Proxy Settings in the Actions pane, and check Enable proxy. Proxy functionality is off by default; rewrite rules pointing at another host do nothing until this is enabled.
- Add a rewrite rule whose action URL is absolute. A rewrite to an absolute URL is what triggers ARR to proxy:
<rule name="Proxy to backend" stopProcessing="true">
<match url="^app/(.*)" />
<action type="Rewrite" url="http://localhost:5000/{R:1}" />
</rule>
The action type is Rewrite, not Redirect — the client keeps talking to IIS while IIS talks to the backend. If the backend emits absolute links or Location headers pointing at itself, outbound rules can rewrite the response before it leaves the proxy; the walkthrough above covers that pattern.
Testing rules
The URL Rewrite UI in IIS Manager has a Test pattern button in the rule editor — it evaluates a sample input against the regex and shows every back-reference, which resolves most "why did {R:1} come out wrong" questions before deployment.
For rules that misbehave on live traffic, enable Failed Request Tracing for the relevant status code. The trace log records each rewrite rule evaluation in order — which rules matched, which conditions failed, and what the URL was after each step. That is the authoritative record of what the module actually did; guessing from the browser is not. Redirect chains are also visible in the site's access logs — the IIS log fields to read are sc-status and cs-uri-stem across consecutive requests from the same client.
Common breakages
- 500.19 after deploying web.config to a server without the module. Error code 0x8007000D, "The configuration section 'rewrite' cannot be read because it is missing a section declaration." IIS refuses to parse the rewrite section because nothing on the server owns it. Fix: install URL Rewrite 2.1 on that server. This is the standard failure when a web.config written on a dev machine ships to a fresh production box.
- Infinite redirect loop behind a load balancer or CDN. When TLS terminates at the load balancer (or Cloudflare) and traffic reaches IIS over HTTP,
{HTTPS}is always OFF, so the HTTPS rule fires on every request forever — the browser reports ERR_TOO_MANY_REDIRECTS. Fix: condition on the forwarded-protocol header instead. Replace the {HTTPS} condition with<add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" />so the rule fires only when the original client connection was HTTP. Confirm which header your balancer sends; X-Forwarded-Proto is the common one. - Rule matches but back-references are empty. The match pattern has no capture group, or the reference index is off — {R:0} is the full matched string, {R:1} the first parenthesized group.
- Redirect rule placed after a rewrite rule that already changed the URL. Rules see the URL as modified by earlier rules. Put redirects (HTTPS, canonical host) first, rewrites after,
stopProcessing="true"on the redirects. - ARR proxy rule returns 404 from the wrong site. Proxy was not enabled at the server level, so the absolute-URL rewrite was treated as a local path. Enable proxy in ARR server settings.
When to hand it over
A wrong redirect rule is a production outage that caches itself — 301s persist in browsers and CDNs after the rule is fixed. Our IIS support team writes and reviews rewrite configurations as routine work: HTTPS enforcement behind load balancers, canonical-host consolidation without redirect chains, ARR reverse proxy setups, and Failed Request Tracing when a rule set misbehaves. An engineer is available on live chat 24/7.
Topics

Sreenivasa Reddy G
Founder & CEO • 15+ years
Sreenivasa Reddy is the Founder and CEO of Medha Cloud, recognized as "Startup of the Year 2024" by The CEO Magazine. With over 15 years of experience in cloud infrastructure and IT services, he leads the company's vision to deliver enterprise-grade cloud solutions to businesses worldwide.
More in Server Support
View all
What Is an Application Server? Types & Examples
8 min read

IIS Application Pool: Settings, Recycling & Crashes
9 min read

IIS Logs: Location, Format & How to Read Them
10 min read

IIS Manager: How to Open & Use It
9 min read

What Is IIS? Windows Web Server Setup, Sites & App Pools
9 min read

Windows Server Download: 2025 & 2022 Evaluation ISOs
8 min read