# HTTP/3 on Windows Server: IIS can, Nginx Win32 cannot

> Enable HTTP/3 on IIS/ASP.NET Core with HTTPS and EnableHttp3, advertise it with Alt-Svc, test QUIC over UDP 443, and understand the Windows Nginx limit.

**Tested on**

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

## The short answer

HTTP/3 is HTTP over **QUIC/UDP**, not TCP. On Windows:

- **IIS / ASP.NET Core** supports HTTP/3 on Windows Server 2022 / Windows 11+ with an HTTPS binding and `EnableHttp3`.
- **Nginx on Windows cannot build `ngx_http_v3_module`**; do not claim Windows Nginx HTTP/3.
- If you need HTTP/3 at the edge, use IIS, a Linux Nginx/Caddy tier, or a CDN — and test it.

HTTP/3 is not automatically faster for every app. It helps on lossy/high-latency links and removes TCP head-of-line blocking; it does not fix a slow database.

## IIS prerequisites

- Windows Server 2022 or later / Windows 11+.
- An **HTTPS** binding (`https`, certificate, SNI).
- `EnableHttp3` registry value.
- UDP 443 allowed through the firewall and any NAT.
- A client that supports HTTP/3 (current Chrome/Edge/Firefox) and can reach UDP 443.

Enable:

```powershell
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\HTTP\Parameters' `
  -Name EnableHttp3 -PropertyType DWord -Value 1 -Force
```

Reboot (or restart the HTTP stack during a maintenance window). Do not bounce HTTP.sys on a busy server without a plan; it affects every HTTP listener, not just IIS.

## Alt-Svc

Browsers discover HTTP/3 from HTTP/1.1 or HTTP/2 via `Alt-Svc`:

```http
Alt-Svc: h3=":443"; ma=86400
```

IIS does not always add it for you. For ASP.NET Core, add it early in the pipeline:

```csharp
app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});
```

IIS can also send an Alt-Svc HTTP/2 frame with `EnableAltSvc`; that path requires hostname-based `netsh` certificate bindings, not IP-only bindings.

The first request normally uses HTTP/1.1 or HTTP/2, then the client upgrades. That is expected; it is not “HTTP/3 failed”.

## In-process vs out-of-process

- **In-process** ASP.NET Core: the request reports `HTTP/3`.
- **Out-of-process** (IIS → Kestrel): IIS speaks HTTP/3 to the client, but the reverse-proxy hop to Kestrel is HTTP/1.1, so `HttpRequest.Protocol` reports HTTP/1.1.

Do not use `HttpRequest.Protocol` alone to prove the client used HTTP/3 in an out-of-process deployment.

## Verify

```powershell
netsh http show sslcert hostnameport=lab.example:443
Get-NetFirewallRule -DisplayName '*HTTP*' | Select-Object DisplayName,Enabled
curl.exe --http3 -I https://lab.example/
```

`curl --http3` only works if the curl build includes HTTP/3 support. In a browser, DevTools → Network → Protocol column should show `h3` after the Alt-Svc upgrade. If it shows `h2`, the client did not switch; check UDP 443 and Alt-Svc.

## Nginx on Windows

The official `ngx_http_v3_module` documentation states the module **cannot be built on the Win32 platform**. There is no supported Windows Nginx HTTP/3 termination to enable with a config flag.

Options:

- terminate HTTP/3 at IIS or a Linux reverse proxy/CDN;
- keep Windows Nginx on HTTP/2 and accept that;
- do not advertise `h3` from a server that cannot serve it.

> **Caution: Do not force HTTP/3**
>
> HTTP/3 fallback is a feature. Blocking UDP 443, corporate proxies, and some load balancers will break QUIC; clients must be able to fall back to HTTP/2. Test both paths and keep HTTP/2 enabled.

## When it is worth it

- Mobile/lossy networks, large numbers of parallel assets.
- You already have TLS/HTTP/2 and can open UDP 443.
- You can measure (RUM or controlled clients), not just run a lab curl.

Not worth it when:

- the app is API-only with tiny requests and a fast network;
- your edge cannot pass UDP;
- you would have to break HTTP/2 fallback to “prove” HTTP/3.

## Lab boundary

E1. The lab did not enable IIS HTTP/3 or test QUIC; it only documented the requirements. Nginx 1.28.0 on Windows 11 was verified for HTTP/1.1 on 8081, not HTTP/3. The Nginx Win32 limitation is from the official module documentation.

## Sources

- [Microsoft Learn — ASP.NET Core HTTP/3 on IIS](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/http3?view=aspnetcore-10.0)
- [nginx — ngx_http_v3_module](https://nginx.org/en/docs/http/ngx_http_v3_module.html)
- [RFC 9114 — HTTP/3](https://datatracker.ietf.org/doc/rfc9114/)

---

Source: https://windows.homes/en/server/web/http3/
