Application-Layer Protocol Negotiation
Application-Layer Protocol Negotiation (ALPN) is a Transport Layer Security (TLS) extension that enables the negotiation of application-layer protocols during the TLS handshake, allowing clients and servers to agree on the protocol to use—such as HTTP/1.1 or HTTP/2—over a single secure connection without additional round trips.[1] Defined in RFC 7301 and published by the Internet Engineering Task Force (IETF) in July 2014, ALPN addresses the challenge of multiplexing multiple application protocols on the same transport port, particularly port 443 for HTTPS traffic, thereby improving efficiency and enabling protocol-specific optimizations like certificate selection.[1] It replaces the earlier, non-standard Next Protocol Negotiation (NPN) mechanism, providing a standardized, IANA-registered framework for protocol identifiers as opaque byte strings.[1] In practice, the client advertises a prioritized list of supported protocols in the ClientHello message using the ALPN extension (TLS extension type 16), and the server responds by selecting one protocol in the ServerHello if supported, ensuring both parties proceed with the chosen application layer atop the established TLS session.[1] This integration with TLS 1.2 or higher is mandatory for secure deployments of protocols like HTTP/2, where the "h2" identifier must be used via ALPN to confirm mutual support and mitigate cross-protocol attacks.[2] ALPN's adoption has been pivotal in modern web infrastructure, supporting the transition to multiplexed protocols and extending to other domains such as Web Real-Time Communication (WebRTC) with identifiers like "webrtc"[3] and secure RADIUS authentication. [4] Its role in reducing latency and enhancing security continues to influence evolutions like HTTP/3 over QUIC, where similar negotiation principles apply.Introduction
Definition and Purpose
Application-Layer Protocol Negotiation (ALPN) is a Transport Layer Security (TLS) extension defined in RFC 7301, enabling clients and servers to negotiate the application-layer protocol to be used within a TLS connection before the handshake completes.[1] This mechanism allows the application layer to indicate preferred protocols during the initial TLS exchange, ensuring that the selected protocol is securely agreed upon without requiring additional post-handshake negotiations.[1] The primary purpose of ALPN is to reduce latency associated with protocol selection and upgrades, such as transitioning from HTTP/1.1 to HTTP/2, by avoiding extra round trips that would otherwise be needed after establishing the TLS connection.[1] It facilitates multiplexing multiple application protocols over the same port, typically port 443 for HTTPS, while maintaining secure negotiation entirely within the encrypted TLS framework.[1] By integrating this negotiation into the TLS process, ALPN prevents protocol mismatches that could lead to connection failures or insecure fallbacks.[1] Key benefits include enhanced performance for web traffic through efficient protocol selection and backward compatibility with clients or servers that do not support ALPN, as the extension can be ignored without disrupting the TLS handshake.[1] Although ALPN operates at the application layer, it integrates into TLS at OSI layer 6 (the presentation layer), bridging transport security with higher-level protocol choices.[1]Relation to TLS Handshake
Application-Layer Protocol Negotiation (ALPN) is integrated into the Transport Layer Security (TLS) handshake as an extension that enables protocol selection during the initial exchange of messages. Specifically, the client includes the ALPN extension, identified by type 16 ("application_layer_protocol_negotiation"), in its ClientHello message, containing a list of supported application protocols in order of client preference.[1] The server, upon receiving the ClientHello, selects the most preferred protocol from the list that it supports and includes this single selected protocol in the corresponding ALPN extension within its ServerHello message, thereby confirming the chosen protocol for the connection.[1] This process ensures that the application-layer protocol is negotiated efficiently without requiring additional round trips beyond the standard TLS handshake.[1] ALPN requires TLS version 1.2 or later for full support, as it relies on the extension framework defined in TLS 1.2 (RFC 5246), and is not available in earlier protocols such as SSL 3.0 or TLS 1.0/1.1 without non-standard extensions.[1] In TLS 1.2 and below, the protocol identifiers are sent in plaintext within the handshake messages, while in TLS 1.3, they are protected by encryption as part of the Encrypted Extensions message.[1] Although the TLS extension mechanism was introduced earlier in RFC 3546 for TLS 1.0, ALPN's specification in RFC 7301 aligns it primarily with TLS 1.2 and subsequent versions for interoperability and security.[1] If the server does not support any of the protocols proposed by the client, it must issue a fatal "no_application_protocol" alert (code 120) and terminate the handshake, preventing fallback to a default protocol as no such mechanism is defined in the ALPN specification.[1] Unlike post-handshake negotiation approaches, such as those in some encrypted client hello extensions, ALPN completes its protocol selection by the end of the ServerHello phase, ensuring the agreed protocol is established before any application data is exchanged following the Finished messages.[1] This timing integrates seamlessly with the TLS security model, allowing immediate application-layer communication upon handshake completion.[1]Technical Mechanism
Negotiation Process
The Application-Layer Protocol Negotiation (ALPN) extension integrates protocol selection directly into the Transport Layer Security (TLS) handshake, allowing clients and servers to agree on an application-layer protocol without additional network delays.[1] In the initial phase, the client initiates negotiation by including the ALPN extension in its ClientHello message. This extension contains a ProtocolNameList, which is an ordered sequence of protocol identifiers supported by the client, listed in descending order of preference. For instance, a client might advertise "h2,http/1.1" to indicate a preference for HTTP/2 over HTTP/1.1.[1] The order of this list explicitly signals the client's priorities, enabling the server to select the most preferred mutually supported option.[1] Upon receiving the ClientHello, the server examines the ProtocolNameList and determines if it supports any of the advertised protocols. If a match exists, the server selects the highest-priority protocol from the client's list that it can handle and includes the ALPN extension in its ServerHello message, specifying the chosen protocol identifier.[1] This selection binds the protocol to the ensuing TLS session. However, if the server supports none of the client's proposed protocols, it must terminate the handshake by sending a fatal "no_application_protocol" alert (AlertDescription 120), preventing further connection establishment.[1] In cases where the server chooses not to participate in ALPN—by omitting the extension from the ServerHello—no protocol is explicitly negotiated, and the client must proceed by assuming a default or fallback application protocol suitable for the connection.[1] Clients are required to handle such absences gracefully, typically reverting to a baseline protocol like HTTP/1.1 for web traffic, ensuring compatibility without aborting the session.[1] Once the TLS handshake completes, the selected (or fallback) protocol remains definitive for the connection; ALPN does not permit renegotiation of the application protocol after this point, avoiding potential security risks and maintaining efficiency.[1] A key advantage of embedding ALPN within the TLS handshake is its elimination of extra round trips that would otherwise be needed for application-layer negotiation post-encryption, streamlining the overall connection setup compared to separate protocol discovery mechanisms.[1] This client-offered, server-selected model ensures orderly preference resolution while integrating seamlessly with the TLS framework's security properties.[1]Extension Format and Identifiers
The Application-Layer Protocol Negotiation (ALPN) extension is identified by the value 16 in the TLS extensions space, as registered with the Internet Assigned Numbers Authority (IANA).[5][6] In the ClientHello message, the ALPN extension data consists of an opaque vector known as the ProtocolNameList, which encodes a length-prefixed list of protocol names in the client's order of preference.[7] This structure is defined as a sequence of ProtocolName entries, where each ProtocolName is an opaque byte string of 1 to 255 bytes, prefixed by its length (1 to 255 octets).[7] The overall ProtocolNameList length ranges from 2 to 65,535 bytes to fit within TLS message constraints, ensuring no empty or truncated names are permitted.[7] For the ServerHello message, the ALPN extension data similarly uses a ProtocolNameList but contains exactly one ProtocolName entry, representing the single protocol selected by the server from the client's offered list.[8] This selected name must match one proposed by the client exactly and must be non-empty; the server omits the extension entirely if no compatible protocol is available.[8] Protocol identifiers, or ProtocolName values, are registered strings maintained in the IANA "TLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs" registry, which operates under an Expert Review policy to ensure specifications are publicly available and documented.[9] These identifiers are opaque byte strings encoded in UTF-8, typically short ASCII sequences without wildcards or special characters, such as "http/1.1" for HTTP/1.1 (hex: 0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31) or "h2" for HTTP/2 over TLS (hex: 0x68 0x32).[10][9] No compression is applied to these identifiers, preserving their exact byte representation.[10] The server must select precisely one matching protocol or decline the negotiation by sending a "no_application_protocol" alert (value 120), resulting in handshake failure if the selection is invalid or absent when required.[8] The total length of the ALPN extension is constrained by the underlying TLS message size limits, typically up to 2^16-1 bytes for extensions in aggregate.[7]Historical Development
Next Protocol Negotiation
Next Protocol Negotiation (NPN) was introduced by Google in January 2010 through an IETF draft authored by Adam Langley, aimed at enabling the selection of application-layer protocols, such as the experimental SPDY protocol, over existing TLS connections on port 443 without requiring additional TCP handshakes or port allocations.[11] The design sought to multiplex multiple protocols efficiently while allowing fallback to standard HTTP for incompatible intermediaries, and it was implemented in early versions of Google Chrome to facilitate SPDY deployment as a precursor to HTTP/2.[11] The negotiation process operated as a TLS extension rather than a full handshake modification. The client advertised support by including thenext_protocol_negotiation extension in its ClientHello message (with empty extension data), prompting the server to respond in the ServerHello with an unencrypted list of supported protocols encoded as length-prefixed strings. After sending its ChangeCipherSpec but before its Finished message, the client sent an EncryptedExtensions message specifying the chosen protocol.[12] This separation ensured the final selection was encrypted but left the server's capabilities visible during the initial handshake phase.
NPN's design exhibited key limitations that undermined its reliability and security. The unencrypted protocol list in the ServerHello exposed server capabilities to potential eavesdroppers or network intermediaries, facilitating traffic discrimination—particularly problematic for privacy-focused protocols like those used in Tor networks.[12] Additionally, the mechanism was incompatible with TLS session resumption, as protocol selection applied only to new full handshakes and could not be preserved in abbreviated ones, leading to inconsistent behavior across connections.[12] These issues rendered NPN inefficient for widespread adoption.
These flaws, including vulnerability to analysis and resumption incompatibilities, prompted its deprecation in favor of a more integrated approach. Google announced intentions to phase out NPN from Chrome and its servers by late 2014, with full removal occurring in Chrome version 51 in May 2016 after a brief disablement trial in 2015.[13][14]
Standardization of ALPN
The development of Application-Layer Protocol Negotiation (ALPN) began within the IETF Transport Layer Security (TLS) Working Group in 2012, primarily to address the limitations of the proprietary Next Protocol Negotiation (NPN) extension, which lacked standardization and broad interoperability. An initial individual draft, draft-friedl-tls-applayerprotoneg-00, was published on October 15, 2012, proposing a standardized TLS extension for negotiating application-layer protocols during the handshake. The Working Group adopted the draft, leading to the first WG version, draft-ietf-tls-applayerprotoneg-01, released on April 25, 2013. This progression involved iterative reviews, including WG last calls and IESG evaluations, to refine the extension's format, security considerations, and integration with existing TLS mechanisms. ALPN achieved formal standardization with the publication of RFC 7301 on July 11, 2014, as a Proposed Standard by the IETF.[15] Titled "Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension," the RFC defines ALPN as a client-initiated extension in the TLS ClientHello message, enabling servers to select from a list of proposed protocols without additional round trips. It explicitly obsoletes NPN by providing a standards-track alternative that ensures compatibility across implementations.[15] Following its initial publication, ALPN saw integration into subsequent TLS versions without substantive modifications to its core mechanism. In TLS 1.3, specified in RFC 8446 (published August 2018), ALPN remains a supported extension for protocol selection, maintaining its role in the streamlined handshake while benefiting from TLS 1.3's enhanced security features. Minor clarifications have been issued via errata to RFC 7301, addressing issues such as protocol identifier formatting and registry procedures, but these do not alter the protocol's functionality.[16] ALPN's standardization has influenced related protocols, mandating its use in specific contexts for interoperability. For instance, RFC 7540 (May 2015), which defines HTTP/2, requires ALPN with the "h2" identifier for TLS-secured connections to ensure proper negotiation. More recently, RFC 8833 (January 2021) specifies dedicated ALPN labels, such as "webrtc" and "c-webrtc," for Web Real-Time Communication (WebRTC) to facilitate secure peer-to-peer media sessions over DTLS.Adoption and Support
Cryptographic Libraries
OpenSSL has supported the Application-Layer Protocol Negotiation (ALPN) extension since version 1.0.2, released on January 22, 2015, which introduced the necessary APIs and command-line options for protocol advertisement during TLS handshakes. Full integration with TLS 1.3, including seamless ALPN handling in post-handshake scenarios, was achieved in OpenSSL 3.0, released on September 7, 2021, enabling robust support for modern protocols like HTTP/2 and HTTP/3. GnuTLS implemented ALPN starting with version 3.2.0, released on May 10, 2013, providing initial support for the extension in both client and server modes to facilitate protocol selection over TLS.[17] Enhancements in version 3.8, released in February 2023, improved handling of the "h3" protocol identifier for HTTP/3, optimizing QUIC-based negotiations and ensuring compatibility with emerging transport protocols.[18] BoringSSL, Google's fork of OpenSSL, has included native ALPN support since its initial release in June 2014, inheriting and extending the extension's functionality for high-performance environments. Widely used in Google Chrome and production services, BoringSSL accommodates interactions between ALPN and Encrypted Client Hello (ECH) as outlined in 2025 IETF drafts, maintaining protocol negotiation integrity amid privacy enhancements. Among other notable libraries, Mozilla's Network Security Services (NSS) added ALPN support in version 3.15.5, released in February 2014, with APIs for enabling the extension via socket options like SSL_ENABLE_ALPN.[19] The Java Secure Socket Extension (JSSE), part of Oracle's JDK, introduced ALPN APIs in JDK 8u60, released in August 2015, allowing developers to specify protocol lists for negotiation.[20] This support has matured in subsequent LTS releases, such as JDK 21, released in September 2023, with refined handling for TLS 1.3 and extended protocol identifiers. In practical deployments, AWS IoT Core relaxed its ALPN requirement in October 2024, allowing connections without the extension for certain constrained devices while preserving security for others.[21] No major changes to ALPN implementations occurred in cryptographic libraries between 2023 and 2025; however, post-quantum TLS 1.3 drafts from the IETF continue to reference ALPN without modifications, focusing instead on hybrid key exchanges.[22]Browsers and Web Servers
Google Chrome and Microsoft Edge, both based on the Chromium engine, have supported ALPN for HTTP/2 negotiation since version 40 in April 2015, with full stable implementation by version 41 later in 2015. Mozilla Firefox introduced ALPN support for HTTP/2 starting with version 27 in 2014, becoming enabled by default in version 36 in 2015.[23] Apple Safari added ALPN for HTTP/2 in iOS 9 and macOS 10.11, both released in 2015. By 2023, all major browsers—Chrome, Edge, Firefox, and Safari—had integrated support for the "h3" ALPN identifier to enable HTTP/3 over QUIC, with widespread deployment in stable releases. As of November 2025, HTTP/3 ("h3") support via ALPN is used by approximately 41% of websites, reflecting growing adoption alongside HTTP/2.[24][25] On the server side, Nginx has supported ALPN for HTTP/2 since version 1.9.5, released in 2015, requiring OpenSSL 1.0.2 or later for the extension.[26] The Apache HTTP Server followed suit with ALPN integration for HTTP/2 via the mod_http2 module starting in version 2.4.12, also in 2015.[27] All major web servers, including Nginx and Apache, now mandate ALPN for HTTP/2 and subsequent protocols like HTTP/3, as it is essential for efficient TLS handshake negotiation.[28] Adoption of ALPN in browsers reached near-universal levels among modern clients by 2020, with over 95% of browser traffic capable of negotiating HTTP/2 via ALPN, driven by performance gains in multiplexing and header compression.[29] Servers like Cloudflare enforce ALPN for HTTP/2 connections to optimize edge performance, reducing latency in high-traffic scenarios.[30] Post-2023, there has been no decline in ALPN support across browsers and servers; instead, it remains a foundational requirement for advanced protocols.[31] The ongoing development of Encrypted Client Hello (ECH), approved for publication as an RFC in 2025, maintains ALPN visibility in the outer TLS handshake to ensure compatibility with existing infrastructure while encrypting sensitive inner details. This design preserves seamless protocol negotiation without disrupting browser-server interoperability up to 2025.[32]Applications and Examples
HTTP Negotiation
In HTTP protocol selection, Application-Layer Protocol Negotiation (ALPN) enables clients and servers to agree on the HTTP version during the TLS handshake, optimizing web traffic efficiency. For instance, a client supporting both HTTP/2 and HTTP/1.1 typically offers the ALPN protocol identifiers "h2" followed by "http/1.1" in order of preference, allowing the server to select "h2" if it supports HTTP/2's multiplexing capabilities, which reduce latency through concurrent request handling over a single connection.[33][7] HTTP/3 further integrates ALPN by using the "h3" identifier over QUIC, a UDP-based transport that replaces TCP to mitigate head-of-line blocking. During the initial TLS 1.3 handshake within QUIC's connection establishment, the client proposes "h3" via ALPN, and the server selects it to enable HTTP/3's enhanced performance for unreliable networks. A typical ALPN handshake for HTTP negotiation appears as follows in the TLS messages:- ClientHello ALPN extension: The ProtocolNameList might include
0x02 0x68 0x32(length 2, "h2") followed by0x08 0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31(length 8, "http/1.1"), prefixed by the total list length. - ServerHello ALPN extension (if selecting HTTP/2):
0x02 0x68 0x32(length 2, "h2").