ALPN: how TLS chooses HTTP/2 or HTTP/1.1
ALPN, Application-Layer Protocol Negotiation, is a TLS extension that lets the client and the server agree which protocol they will speak inside the encrypted connection, such as HTTP/2 or HTTP/1.1. The choice is made during the TLS handshake, so it costs no extra round trip. Browsers rely on it to use HTTP/2 over HTTPS, and HTTP/3 requires it. ALPN is defined in RFC 7301 and belongs to the TLS protocol section.
Quick facts
- Defined in
- RFC 7301 (2014)
- Sent in
- the ClientHello; the server's choice comes back in the handshake
- Common identifiers
h2(HTTP/2),http/1.1,h3(HTTP/3)- If nothing matches
- the server may end the handshake with
no_application_protocol, or continue without choosing - Check it
openssl s_client -alpn h2,http/1.1orcurl -v
What ALPN does
One port, 443, carries several protocols: HTTP/1.1, HTTP/2 and others. Before any request is sent, client and server must know which one they are speaking. Without ALPN that would take an extra exchange after the encrypted connection is ready. ALPN puts the question into the handshake itself, so the first request after the handshake already uses the agreed protocol.
ALPN replaced NPN, an earlier extension created for SPDY, the experimental protocol that became HTTP/2. In NPN the client chose; in ALPN the server chooses from the client's list.
How the negotiation works
The client offers. Its first message, the ClientHello, contains an ALPN extension listing the protocols it supports, in order of preference. A browser typically sends
h2and thenhttp/1.1. The same message lists the cipher suites the client accepts.The server chooses. It picks one protocol from the list that it also supports. In TLS 1.2 the choice comes back in the ServerHello; in TLS 1.3 it is sent in the encrypted part of the server's reply, the EncryptedExtensions message. In a full handshake that part is encrypted with keys from an ephemeral key exchange, the one that gives TLS 1.3 forward secrecy.
Both use it. After the handshake, the connection carries the chosen protocol from the first byte.
The identifiers are registered with IANA. Each is a short string, such as h2 for HTTP/2 over TLS.
When no protocol matches
RFC 7301 tells the server to end the handshake with a fatal no_application_protocol alert when it supports none of the offered protocols. OpenSSL's own test server does exactly that; openssl s_client then reports SSL alert number 120.
Web servers usually behave more gently. If the client offered h2 and http/1.1 and the server has HTTP/2 turned off, the server picks http/1.1 or makes no choice, and the browser falls back to HTTP/1.1. A missing h2 therefore makes a site slower, not unreachable. The handshake fails only when a client insists on a protocol the server does not have, which happens mostly with specialised clients, such as gRPC, that require HTTP/2.
ALPN and HTTP/2, HTTP/3
HTTP/2. Browsers support HTTP/2 only over TLS and negotiate it only through ALPN. A server that has HTTP/2 enabled but cannot offer
h2in ALPN, for example because its TLS library is too old, serves HTTP/1.1 to every browser. In nginx, HTTP/2 is turned on withhttp2 on, and nginx then offersh2automatically; see installing on nginx.HTTP/3. HTTP/3 runs over QUIC, which carries the TLS 1.3 handshake inside it. QUIC requires ALPN, and HTTP/3 is identified as
h3. Browsers usually learn that a site offers HTTP/3 from anAlt-Svcheader or a DNS record, then connect over QUIC and confirm it through ALPN.
ALPN and certificates
ALPN also carries one certificate-related job. The ACME validation method TLS-ALPN-01, defined in RFC 8737, proves control of a domain over port 443: the authority connects offering only the protocol acme-tls/1, and the server answers with a special temporary certificate instead of its usual one. That lets a server validate a name without serving files over port 80. How validation methods compare is on ACME.
ALPN does not affect which certificate a site normally presents. That is chosen by the hostname the client sends, called SNI.
How to check ALPN
Offer protocols with OpenSSL and read which one the server picked:
$ openssl s_client -connect example.com:443 -servername example.com -alpn h2,http/1.1 </dev/nullThe output contains ALPN protocol: h2 when HTTP/2 was chosen, or No ALPN negotiated when the server picked nothing. Curl shows the same exchange in its verbose output:
$ curl -v https://example.com/ -o /dev/null
* ALPN: curl offers h2,http/1.1
* ALPN: server accepted h2Older curl versions word these lines differently, but they name the offered and accepted protocols. In a browser, the developer tools' network panel shows the protocol of each request, usually as h2 or h3. More checks are on OpenSSL commands.
FAQ
What is ALPN?
Application-Layer Protocol Negotiation, a TLS extension in which the client lists the protocols it can speak and the server picks one during the handshake. It is how browsers and servers agree on HTTP/2 or HTTP/1.1 without an extra round trip.
Is ALPN required for HTTP/2?
For HTTP/2 over TLS, yes in practice: browsers negotiate HTTP/2 only through ALPN. If a server cannot offer h2 in ALPN, browsers use HTTP/1.1.
What does "No ALPN negotiated" mean?
The server did not choose any of the protocols the client offered. Usually the connection continues with HTTP/1.1; it means HTTP/2 is not available on that server or that hostname.
What is the difference between ALPN and SNI?
Both are TLS extensions sent in the ClientHello. SNI names the website the client wants, so the server can pick the right certificate; ALPN names the protocol the client wants to speak inside the connection.
What is acme-tls/1?
The ALPN identifier used by the TLS-ALPN-01 validation method of ACME. A certificate authority connects with it to check that the server controls the domain, and the server answers with a temporary validation certificate.
How do I check if a site uses HTTP/2?
Run openssl s_client with -alpn h2,http/1.1 and look for ALPN protocol: h2, or run curl -v and look for the line saying the server accepted h2.