# IIS URL Rewrite: redirects that do not loop

> Install URL Rewrite, write HTTP-to-HTTPS and canonical-host rules, understand rule order and stopProcessing, and test 301s without breaking a reverse proxy.

**Tested on**

- Build: 26100.33650
- Edition: Standard / Datacenter
- Architecture: x64
- Evidence: E1
- Verified: 2026-10-29

## The short answer

URL Rewrite is an **IIS extension**, not a built-in role service. It rewrites or redirects a request based on rules in `web.config`.

Use it for:

- HTTP → HTTPS redirect;
- `www` ↔ apex canonical host;
- removing trailing slashes or legacy paths;
- short, deterministic URL mappings.

Do **not** use it as a reverse proxy. Proxying is ARR; rewriting changes the URL IIS serves, proxying forwards the request to another server.

## Install and verify

Download the x64 URL Rewrite module from Microsoft, install, then:

```powershell
Get-WebGlobalModule -Name RewriteModule
```

If it is absent, the rules below are ignored or the site returns 500.19 “module not found”.

## HTTP → HTTPS

```xml
<configuration>
  <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>
</configuration>
```

- `{R:1}` is the captured path from `(.*)`.
- `redirectType="Permanent"` sends **301**; use `Found` (302) while testing.
- `stopProcessing="true"` stops later rules for this request.

Test:

```powershell
curl.exe -I http://lab.local/
curl.exe -I https://lab.local/
```

The first should return `301` with a `Location: https://...`; the second should return `200` and must not redirect again.

## Canonical host

```xml
<rule name="Canonical host" stopProcessing="true">
  <match url="(.*)" />
  <conditions>
    <add input="{HTTP_HOST}" pattern="^www\.example\.com$" />
  </conditions>
  <action type="Redirect" url="https://example.com/{R:1}" redirectType="Permanent" />
</rule>
```

Put the canonical-host rule **before** generic path rules. A rule that redirects everything to `https://example.com` can also catch the health-check path and create a loop if the proxy rewrites `Host`.

## Reverse proxy loops

Behind ARR/Nginx, IIS may see `HTTP` even when the client used HTTPS. A naive `{HTTPS} = OFF` rule then redirects forever.

Fix the trust boundary first:

- terminate TLS at the proxy and forward `X-Forwarded-Proto`;
- configure ARR to preserve the host/proto;
- only then add a condition for the forwarded header, or exclude the proxy's health-check path.

Do not “fix” a loop by disabling the HTTPS redirect for all traffic.

> **Caution: 301 is cached**
>
> Browsers and CDNs cache permanent redirects. Test with 302 first, and use a private window or `curl` so a bad 301 does not haunt you for hours.

## Rule order and scope

- Rules run top to bottom; `stopProcessing` stops the chain.
- A rule in the site root `web.config` inherits into applications; a child can clear or override.
- Conditions are ANDed; multiple `<add>` entries all must match.
- `{HTTP_HOST}` includes the port in some cases; use `{HTTP_HOST}` carefully with non-default ports.

## Verify and roll back

```powershell
Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
  -Filter 'system.webServer/rewrite/rules' -Name '.'
```

Keep a copy of the previous `web.config`, test with `curl -I`, and remove the rule if the redirect chain is wrong. URL Rewrite does not replace a backup of the site configuration.

## Lab boundary

This page is E1: the lab captured IIS bindings and app pools on Windows 11, but did not install URL Rewrite or test HTTPS redirects. The XML is a starting point; validate it on the target Server 2025 build.

## Sources

- [Microsoft Learn — URL Rewrite configuration](https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/url-rewrite-module-configuration-reference)
- [Microsoft Learn — Creating rewrite rules](https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/creating-rewrite-rules-for-the-url-rewrite-module)
- [Microsoft Learn — URL Rewrite and ARR](https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing)

---

Source: https://winbook.fyi/en/server/web/iis-url-rewrite/
