# Alt-Svc Header: How Browsers Discover HTTP/3

> Alt-Svc advertises an alternative protocol for an origin. How h3=":443"; ma=86400 moves browsers to HTTP/3, what clear does, and how HTTPS DNS records differ.

Source: https://howhttpworks.com/headers/alt-svc
Last reviewed: 2026-10-04

> **TL;DR:** `Alt-Svc` is how a server says "I am also reachable over this other protocol or port." In practice it is the header that moves browsers from HTTP/2 over TCP to HTTP/3 over QUIC, typically `Alt-Svc: h3=":443"; ma=86400`. The first visit still uses TCP unless you also publish an HTTPS DNS record.

## What a response looks like

```http
HTTP/2 200
content-type: text/html
alt-svc: h3=":443"; ma=86400
```

Each entry is `protocol-id="authority"` plus parameters (RFC 7838 section 3). The protocol id is an ALPN token: `h3` for HTTP/3 (RFC 9114), `h2` for HTTP/2. The authority is a quoted `host:port`; leaving the host empty (`":443"`) means the same host as the origin. The port is mandatory, and for QUIC it is a UDP port.

Several alternatives can be listed, most preferred first:

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

## Parameters

- `ma` is the freshness in seconds. The default is 86400 (24 hours). A client subtracts the response `Age` from it.
- `persist=1` asks the client to keep the entry across network changes such as moving from Wi-Fi to cellular. Without it, a client is allowed to drop alternatives when its network configuration changes.
- `clear` is a standalone value, not a parameter. `Alt-Svc: clear` wipes all cached alternatives for the origin.

## How the switch to HTTP/3 happens

1. The browser connects with TCP and TLS (HTTP/1.1 or HTTP/2) because it cannot know the server speaks QUIC.
2. The response includes `Alt-Svc: h3=":443"`.
3. For later requests to that origin, the browser attempts QUIC against the advertised endpoint.
4. If UDP 443 is blocked (common on corporate networks and some firewalls) or the QUIC handshake fails, the browser keeps using TCP.

This is why "is HTTP/3 working?" checks that look only at the first load are misleading. Reload, or look at the protocol column in DevTools on the second navigation.

## Alt-Svc versus the HTTPS DNS record

Alt-Svc is learned after a connection exists. RFC 9460 defines the `HTTPS` DNS record, which carries the same kind of information (an `alpn` list such as `h3,h2`) at resolution time, so a capable client can open QUIC on the very first request.

```text
example.com. 300 IN HTTPS 1 . alpn="h3,h2"
```

The two are complementary. RFC 9460 section 9.3 covers their interaction: when both are present the client has to satisfy the constraints of both, not treat them independently. Keep them consistent. Advertising `h3` in DNS while the server stops answering QUIC gives clients a failed attempt and a fallback on every visit.

## Enabling it

nginx (HTTP/3 support arrived in 1.25.0 and needs a build with QUIC; `http2 on` is the 1.25.1+ syntax):

```nginx
server {
    listen 443 ssl;
    listen 443 quic reuseport;
    http2 on;
    http3 on;

    add_header Alt-Svc 'h3=":443"; ma=86400' always;
}
```

Open UDP 443 in the firewall and security group too. The header alone does nothing if the port is closed. If a CDN terminates TLS for you and has HTTP/3 enabled, check the response for an `alt-svc` header before adding your own.

## Rolling it back

Removing the header does not disable HTTP/3 for clients that already cached the entry; they keep trying until `ma` expires. To retire QUIC cleanly, send `Alt-Svc: clear` for at least as long as your previous `ma`, then stop serving QUIC. A short `ma` during a rollout (for example 3600) keeps this cheap.

## Alt-Used

When a client sends a request over an alternative service it can include `Alt-Used: example.com:443` (RFC 7838 section 5) so the server can detect loops and balance load. Do not treat it as authentication.

## Verify

```bash
curl -sI https://example.com | grep -i alt-svc
curl -sI --http3 https://example.com | head -1
```

The second command needs a curl built with HTTP/3 support. If it fails while Alt-Svc is present, suspect UDP 443 filtering before suspecting the server config.

## Related

- [Connection](https://howhttpworks.com/headers/connection), [Via](https://howhttpworks.com/headers/via)
- [HTTP/1.1 vs HTTP/2](https://howhttpworks.com/compare/http1-vs-http2)
