The Alt-Svc header explained: how browsers discover HTTP/3
HTTP/3 has a chicken-and-egg problem: a browser would need to know that a server speaks QUIC before it can ask. The Alt-Svc header is the answer – and the reason the very first request never runs over HTTP/3.
The problem
HTTP/1.1 and HTTP/2 run over TCP, HTTP/3 over UDP. A browser visiting a domain for the first time has no idea which protocols it supports. It could try TCP and UDP in parallel – but that costs time and traffic on every single first contact across the whole web.
So it works the other way around: the browser connects normally over TCP (HTTP/1.1 or HTTP/2),
and the server mentions in its response that it is also reachable over QUIC. That is exactly
what Alt-Svc – "alternative service" – does.
What it contains
Alt-Svc: h3=":443"; ma=86400
h3– the protocol on offer.h3is final HTTP/3 (RFC 9114). Older servers sometimes also advertise draft versions such ash3-29; that is no longer necessary.":443"– host and port of the alternative service. The empty host before the colon means "same host as now". A different port is possible but rarely useful.ma=86400– max age in seconds: how long the browser may remember that HTTP/3 exists without asking again. 86400 is one day.
Multiple offers are separated by commas. A persist=1 tells the browser to keep the
information across network changes.
How it plays out
- First visit: TCP connection, TLS handshake, HTTP/2. The response carries
Alt-Svc. - The browser stores the entry and finishes loading the current page over HTTP/2.
- From the next connection onwards – often already for that page's assets – it tries QUIC.
- If QUIC fails, it silently falls back to TCP. The visitor never notices.
This is why developer tools often show "h2" on the very first load even though HTTP/3 works perfectly. One reload is usually enough.
Why our check has two lines
The Alt-Svc header is a promise, not proof. A server can advertise HTTP/3
while a firewall swallows UDP/443 – the header is just text inside a TCP response.
That is precisely why h3check tests both separately: "HTTP/3 advertised" reads the header, "HTTP/3 working" then opens a real QUIC connection and fetches the page over it. The combination advertised = YES, working = NO is by far the most common finding – and almost always a firewall issue.
The successor: HTTPS records in DNS
Alt-Svc always costs one detour over TCP. The newer approach is the HTTPS resource record (RFC 9460, related to SVCB), which puts the information in DNS:
example.com. 3600 IN HTTPS 1 . alpn="h3,h2"
The browser learns about HTTP/3 at the same moment it learns the IP address and can speak QUIC immediately, with no TCP detour. Cloudflare publishes these records automatically and other providers are following. Alt-Svc will nonetheless stay necessary for a long time, because not every resolver and browser evaluates the new record type yet.