A TLS connection is already post-quantum when it negotiates a hybrid key-exchange group such as X25519MLKEM768. Your browser’s developer tools, openssl s_client and curl -v can all show you the group’s name. Many connections pass that test. In September 2026, Cloudflare reported that about 70% of browser-generated traffic reaching its network used hybrid ML-KEM on the connection between the visitor and Cloudflare. On a public website, the certificate in that same handshake is still signed with RSA or ECDSA.
In TLS 1.3, the client’s first message, the ClientHello, lists the key-exchange groups it supports, each a named key-agreement algorithm with fixed parameters. It also includes a key share, the client’s public value, for one or more of them. The server picks one group and returns its own key share in the ServerHello. The session keys are post-quantum only if the server picks a post-quantum group, and that choice is what every tool below reports.
Where to look
In the browser
In Chrome, right-click the page, choose Inspect and open the Privacy and security panel, which older versions call Security. Its Connection entry names the protocol, the key-exchange group and the cipher in one sentence, such as “The connection to this site is encrypted and authenticated using TLS 1.3, X25519MLKEM768, and AES_128_GCM.” The panel’s view of the site’s origin lists the same details as Protocol, Key exchange and Cipher. Chrome has offered X25519MLKEM768 by default on desktop since version 131, when it replaced the pre-standard Kyber codepoint with the ML-KEM one.
In Firefox, open the Network panel in the developer tools, reload the page, select the first request and open its Security tab. Under Connection, Key Exchange Group reads mlkem768x25519 for the hybrid group and x25519 for a classical exchange. Mozilla’s enterprise documentation states that Firefox offers hybrid X25519 and ML-KEM-768 key agreement by default.
With openssl s_client
OpenSSL added ML-KEM and the hybrid groups in version 3.5.0, a long-term support release published on April 8, 2025, so check openssl version first. By default, a 3.5 client prefers the hybrid groups and sends key shares for both X25519MLKEM768 and X25519, according to the OpenSSL 3.5 release notes. To find out whether a server supports the hybrid group, offer it nothing else:
openssl s_client -connect www.example.com:443 -groups X25519MLKEM768 -brief </dev/null
-groups sets the colon-separated list of groups the client offers, here a single one. -brief prints a short summary instead of the full session dump, and </dev/null closes the connection after the handshake. A server that accepts the group produces this line:
Negotiated TLS1.3 group: X25519MLKEM768
Any other outcome means the server didn’t accept the group. A TLS 1.3 server that shares none of your groups has to abort with a handshake_failure or insufficient_security alert, which OpenSSL reports as number 40 or 71. Without -groups, OpenSSL offers its defaults, and a server that picks plain X25519 produces a Temp Key line ending in X25519, 253 bits instead of the Negotiated line. Depending on the version, OpenSSL labels it Peer Temp Key or Server Temp Key.
With curl
curl uses the TLS library it was built with, which curl -V names on its first line. Built on OpenSSL 3.5 or later, curl offers the hybrid group by default, and verbose mode reports the result:
curl -sv -o /dev/null https://www.example.com/ 2>&1 | grep 'SSL connection'
On a build that uses OpenSSL, the matching line has four fields:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ecPublicKey
The third field is the group. The fourth is the type of signature the server made over the handshake: id-ecPublicKey for ECDSA, RSASSA-PSS for RSA. To test the hybrid group on its own, add --curves X25519MLKEM768, as curl’s own guide to post-quantum TLS does. Builds on GnuTLS or wolfSSL print a shorter line without the group.
Reading the group name
X25519MLKEM768 joins two algorithm names. X25519 is classical elliptic-curve Diffie-Hellman over Curve25519. ML-KEM-768 is the middle parameter set of ML-KEM (Kyber), the lattice-based key encapsulation mechanism, or KEM, that NIST published as FIPS 203 on August 13, 2024. In TLS, the client sends an encapsulation key and the server answers with a ciphertext, and both sides end up with the same shared secret.
RFC 10024, published in August 2026, specifies the group for TLS 1.3. IANA’s TLS Supported Groups registry lists it as recommended at codepoint 0x11EC (4588), the two-byte number the handshake actually sends.
The bytes show how the halves combine. The client’s key share is 1,216 bytes: a 1,184-byte ML-KEM-768 encapsulation key followed by a 32-byte X25519 public value. The server’s is 1,120 bytes: a 1,088-byte ML-KEM ciphertext followed by its own 32-byte X25519 value. Each side ends up with two 32-byte secrets, and TLS uses their 64-byte concatenation as the input to its key schedule. A classical X25519 exchange sends 32 bytes each way. On the wire, the ML-KEM part precedes the X25519 part despite the name (RFC 10024, section 4.1), which is the order Firefox’s label follows. For what the extra bytes do to packet counts and firewalls, see what larger keys do to your network.
If a tool shows X25519Kyber768Draft00 (0x6399), one end is running pre-standard code. Chrome used that codepoint before version 131, and IANA now marks it obsolete.
What hybrid key exchange protects
Hybrid key exchange protects a session’s confidentiality against harvest-now-decrypt-later, in which an adversary records encrypted traffic and decrypts it once a cryptographically relevant quantum computer exists, meaning one large and reliable enough to run Shor’s algorithm against keys in real use. Shor’s algorithm would recover the X25519 secret from the recorded public values. No known quantum algorithm does the same for ML-KEM, and the session keys depend on both secrets, so the recording stays unreadable unless the attacker can also break ML-KEM. The X25519 half protects against the opposite risk, a flaw in ML-KEM or in a new implementation of it. For the combiner that derives one key from both secrets, see how hybrid cryptography works, byte by byte.
Your deadline depends on how long the data must stay confidential. A session that must stay secret for ten years needs key exchange that resists quantum attack for ten years from the day it ran.
Authentication is still classical. The server signs the handshake with the private key that matches its certificate, and a certificate authority signed the certificate. Version 2.3.1 of the CA/Browser Forum’s Baseline Requirements, the rules publicly trusted certificate authorities follow, took effect on October 4, 2026, and permits only RSA and ECDSA keys in publicly trusted TLS certificates (section 6.1.5). Your tools show this half too. OpenSSL 3.5’s Signature type line gives the IANA scheme name, such as ecdsa_secp256r1_sha256. In curl’s output, the fourth field gives the type, and Firefox shows it as Signature Scheme.
The signature has no bearing on the secrecy of a recorded session. Forging it helps only an attacker who impersonates the server while the handshake is in progress, so a classical certificate becomes exploitable only once a cryptographically relevant quantum computer exists. Keys that stay trusted for decades, such as root and firmware-signing keys, still need post-quantum replacements well before then.
When the result is classical
A classical result has three possible causes, and each one has a different owner.
The client may not implement the group. Support varies across older browsers, OpenSSL before 3.5 and the TLS libraries in language runtimes, operating systems and embedded devices, and curl inherits its library’s support. Cloudflare’s September 2026 post describes a domain whose visitors were mostly non-browser clients without support for X25519MLKEM768 or TLS 1.3.
The server may not offer it. Its TLS library may predate ML-KEM, or its configuration may name its groups explicitly, which replaces the library’s defaults. On nginx, the default ssl_ecdh_curve auto uses OpenSSL’s built-in list, while ssl_ecdh_curve prime256v1:secp384r1; leaves the hybrid group out even on OpenSSL 3.5 (nginx documentation). A server can also support the hybrid group and still pick X25519, because in TLS 1.3 the server makes the choice.
A middlebox may have answered: any device on the path that inspects or terminates traffic. One that terminates TLS, such as an inspection proxy, a load balancer or a content delivery network (CDN) edge, runs its own handshake, so your result shows that device’s choice. On a corporate network, the browser may be reporting its handshake with the inspection proxy. For a site served through a CDN, the browser check covers only the visitor-to-edge connection. The edge-to-origin handshake is separate, and in the same September 2026 post, Cloudflare reported that about 15% of the origins it connects to used hybrid ML-KEM.
A server or middlebox that mishandles the larger ClientHello fails differently. It breaks the connection, which Chrome often reports as ERR_CONNECTION_RESET, instead of completing the handshake with a classical group. The tldr.fail site documents the bug: some implementations assume one read returns the whole ClientHello, and a hybrid key share can make the message too large for one packet.
A three-step check for your own endpoints
Run these from a machine outside your corporate network, so you’re testing your servers and not an inspection proxy.
- Check your tools.
openssl versionshould report 3.5.0 or later, and the first line ofcurl -Vshould name OpenSSL 3.5 or later, or another TLS library with ML-KEM support. - Offer only the hybrid group. For each public hostname, run
openssl s_client -connect HOST:443 -groups X25519MLKEM768 -brief </dev/null. The lineNegotiated TLS1.3 group: X25519MLKEM768means the server supports the group, and an alert or a TLS 1.2 connection means it doesn’t. - Offer the defaults and read both halves. Run the same command without
-groups. If step 2 succeeded but this run shows X25519 on a Temp Key line, the server supports the hybrid group but prefers the classical one, so the fix is the server’s group order. Either way, the Signature type line names the classical signature still to migrate.
For a site served through a CDN or a load balancer, repeat steps 2 and 3 against the origin’s own address. Keep the public hostname in Server Name Indication (SNI), the ClientHello field that names the site you want:
openssl s_client -connect 203.0.113.10:443 -servername www.example.com -groups X25519MLKEM768 -brief </dev/null
Our Hybrid Cryptographic Implementations course covers the engineering behind these results: construction mechanics for hybrid key exchange and signature schemes in TLS, SSH, IPsec, S/MIME and code signing, performance measurement, and the global policy disagreement over when to exit hybrid modes.
Start with step 2 on the hostnames that serve your most sensitive data, and save each output with its date. Each hostname that fails has a server, or a TLS-terminating device such as a load balancer, that needs the hybrid group enabled.