Post-Quantum TLS Is Already Here: How to Check Your Own Systems
Hybrid X25519MLKEM768 key exchange is on by default in major browsers and libraries. See where it runs, where it's missing, and how to test your servers.
Post-quantum TLS is already in use. Most current browsers and many server libraries negotiate a hybrid key exchange called X25519MLKEM768, which pairs a classical curve with the NIST-standardised ML-KEM, so an attacker would have to break both. Your browser probably supports it already. The open question is whether your servers, load balancers and proxies do.
For most people this needs no action beyond keeping software updated. For anyone who runs servers, it's a short check you can do this week.
For the background on Q-Day and why recorded traffic matters, see What Is Q-Day?. This post stays on the practical question: where does hybrid TLS run today, and how do you find out whether yours does?
What is hybrid key exchange in TLS?
TLS is the protocol behind the padlock in your browser. At the start of every connection, the two sides agree on a fresh secret key. That step is the "key exchange", and it is the part a future quantum computer could attack.
A hybrid key exchange runs two methods side by side and mixes both results into the final key. One is a classical elliptic-curve method (X25519). The other is ML-KEM, a post-quantum method. If either one holds, the session key stays secret.
The name tells you what's inside: X25519MLKEM768 is X25519 plus ML-KEM-768. ML-KEM is defined in FIPS 203, which NIST published as a final standard on 13 August 2024. The standard says ML-KEM "is believed to be secure, even against adversaries who possess a quantum computer."
Why hybrid rather than ML-KEM alone? ML-KEM is new, and the classical half is a safety net if a flaw is found in it. Hybrid costs a little more data per handshake and protects against both kinds of failure.
Is X25519MLKEM768 an official standard yet?
Yes. The IETF's RFC 10024, published in August 2026 on the Standards Track, defines three hybrid groups for TLS 1.3 that combine ML-KEM with an ECDHE exchange. Its authors work at PQShield, AWS, Cloudflare and the University of Waterloo.
| Group | Codepoint | Recommended | Client key share |
|---|---|---|---|
| X25519MLKEM768 | 0x11EC (4588) | Yes | 1216 bytes |
| SecP256r1MLKEM768 | 0x11EB (4587) | No | 1249 bytes |
| SecP384r1MLKEM1024 | 0x11ED (4589) | No | 1665 bytes |
Source: RFC 10024. "Recommended" is the column of that name in the IETF TLS Supported Groups registry as the RFC lists it.
For comparison, the X25519 key share on its own is 32 bytes. The ML-KEM-768 part adds 1184 bytes to what the client sends, which is the reason for the packet-size issues covered below.
Where is post-quantum TLS deployed today?
Widely on the client side, much less so on servers. Three data points, each with its date and source:
- Browsers. Cloudflare's compatibility list shows X25519MLKEM768 as the default from Chrome 131, Edge 131, Firefox 132 on desktop and Safari 26. Safari's support is system-wide in iOS 26 and macOS Tahoe 26.
- Share of traffic. In the last week of October 2025, "the majority of human-initiated traffic with Cloudflare" used post-quantum encryption, according to Cloudflare's 2025 report. That is a year-old snapshot of one network, not a global measurement. I couldn't read Cloudflare Radar's live figure for this post, so check it yourself.
- Origin servers. In the same report, Cloudflare found support at "only 0.5% of origins" in 2023, and 3.7% in 2025, "a more than seven-fold increase." Origins are the customer servers behind Cloudflare, and the report notes there is "much more diversity in origins than there are in clients." In practice: the gap between "over half of human traffic" and "3.7% of origins" is the story. Browsers did their part quickly, so protection often exists on the user's side of a connection. Whether it exists end to end depends on the server, and in that report most origins hadn't caught up.
One caveat on these numbers. Cloudflare terminates TLS for a large share of sites, so when a browser talks to a site behind it, the post-quantum handshake happens between the browser and Cloudflare. The hop from Cloudflare to the customer's own server is a separate connection, and that is what the origin figure measures.
Which software supports X25519MLKEM768 by default?
From Cloudflare's compatibility list, read on 25 October 2026:
| Software | Hybrid key agreement |
|---|---|
| OpenSSL | Default from 3.5.0 |
| Go | Default from 1.24 |
| NGINX | Default when compiled with OpenSSL 3.5+ |
| Caddy | Default from 2.10.0 |
| Traefik | Default from 3.4.2 and 2.11.26 |
| Node.js | Default in 24.5.0 and 22.20.0 |
| rustls | Enabled by default since 0.23.27 |
| Java (OpenJDK) | Default in Java 27 (JEP 527), not yet in javax.net.ssl |
The page notes that listings are for reference only and tells you to verify behaviour in the specific version you use. I'm repeating that advice because "supported" and "enabled in your build and configuration" are different things.
OpenSSL 3.5 is a good example of why this matters. The OpenSSL project describes 3.5 as a long-term stable release, supported until 8 April 2030, and says it adds support for ML-KEM, ML-DSA and SLH-DSA. If your servers run an older long-term release, they don't get this from a routine patch. They need a library upgrade.
How can I check whether my own servers use post-quantum TLS?
Start with the one question that matters: does your server pick a hybrid group when a capable client offers it?
- Use a client that supports it. A current browser works for a quick look. For a repeatable test, use OpenSSL 3.5 or later, or BoringSSL's
bssltool. - Connect and read the negotiated group. Cloudflare's origin guide shows
bssl client -connect <host>:443 -curves X25519MLKEM768, where the "ECDHE curve" line should readX25519MLKEM768. With OpenSSL 3.5+, the guide's example showsNegotiated TLS1.3 group: X25519MLKEM768ins_client -briefoutput. - Test every path. The public hostname, the load balancer, the VPN portal, the internal API gateway. Each can be a different product with a different library.
- Test from inside the network too. A corporate proxy that inspects TLS can change what the client negotiates.
If the result shows a classical group such as X25519, the connection works but isn't post-quantum protected. That isn't a failure. It's a finding for your inventory.
What should I do after checking?
Treat the result like any other finding.
- Found support: record it, and note which library and version provides it.
- Found no support: find out who owns the component and when it updates. Ask the vendor for their roadmap.
- Found a break: a connection that fails with a post-quantum capable client is more urgent than one that falls back. See the next section.
Don't switch things off to make a test pass. A vendor who tells you to disable post-quantum key exchange to fix an outage should also tell you when the product will handle it properly.
Going deeper: for security and IT teams
This section assumes you operate TLS endpoints.
What changes on the wire
In TLS 1.3 the client sends key shares in the ClientHello. Under RFC 10024, the X25519MLKEM768 client share is 1216 bytes (a 1184-byte ML-KEM-768 encapsulation key plus 32 bytes of X25519). The server's reply share is 1120 bytes (a 1088-byte ML-KEM ciphertext plus 32 bytes). The two shared secrets are concatenated, ML-KEM first and X25519 second, for 64 bytes in total. The other two groups order them differently, which the RFC attributes to FIPS considerations: for X25519MLKEM768 the ML-KEM implementation must be certified, while for the NIST-curve groups the ECDHE implementation must be.
Middleboxes and ClientHello size
Cloudflare's origin guide says that with X25519 alone the ClientHello almost always fits in one packet, while with ML-KEM added it is typically split across two. TLS 1.3 allows that, but the guide warns it may not be handled well because of "protocol ossification and implementation bugs". Cloudflare's 2025 report traces earlier breakage to "middleboxes, load-balancers, and other software that tacitly assume the ClientHello always fits in a single packet".
What to look for:
- Handshakes that succeed with a classical-only client but hang or reset with a hybrid-capable one.
- Firewalls, WAFs, DDoS appliances and TLS-inspecting proxies that parse the ClientHello, especially on older firmware.
- Intermittent failures only for newer browsers. Compare a packet capture of a working and a failing connection: look for a ClientHello spread over two TCP segments, and for what the device does with the second.
If a server doesn't accept the offered share, it can send a HelloRetryRequest. The guide says that adds one round trip but doesn't break the connection. The RFC itself says nothing on packet splitting, so rely on vendor documentation and your own captures for this part.
Testing from the command line
Use OpenSSL 3.5 or later as the client. The Cloudflare origin guide's example command for a full ML-DSA mutual-TLS setup uses openssl s_client -connect ... -brief and expects Negotiated TLS1.3 group: X25519MLKEM768. The guide doesn't give a key-agreement-only OpenSSL command. I haven't verified one in OpenSSL's own manual for this post, so check the -groups option in the openssl-s_client man page for your version before relying on it. A test that offers only classical groups tells you whether the server still accepts old clients, which is a useful second check.
Server configuration
- NGINX: per Cloudflare's list, it uses X25519MLKEM768 by default when compiled with OpenSSL 3.5 or later. Check the OpenSSL version NGINX is actually linked against, with
nginx -V, not the version on the OS. - Group lists: if your configuration pins a group list (NGINX's
ssl_ecdh_curve, an OpenSSL configGroupsline, Traefik'scurvePreferences), a pinned classical-only list overrides the new default. I haven't verified exact syntax for each product here. Use each vendor's documentation, and put the list in configuration management so you can change it centrally. - Linked libraries: Java applications are not covered by default yet according to Cloudflare's list, which says the Java 27 support (JEP 527) is not yet integrated into
javax.net.ssl. Treat Java services as a separate inventory item.
Inventory and evidence
For each endpoint, record the TLS library and version, the negotiated group with a capable client, the date tested, and the owner. Test again after every library upgrade. Key exchange is the first priority because of harvest-now-decrypt-later. Certificates still use classical signatures. Cloudflare's list shows ML-DSA support in OpenSSL 3.5+ but not in browsers, so don't plan on post-quantum certificates in public TLS yet.
Questions for vendors
- Which RFC 10024 groups does the product offer by default, and which TLS library and version does it ship?
- Does TLS inspection pass hybrid key exchange through, or downgrade it?
- Can we set the group list ourselves?
- When does the next firmware or software release change the default?
Key takeaways
- Hybrid post-quantum key exchange, X25519MLKEM768, is standardised in IETF RFC 10024 (August 2026) and built on NIST FIPS 203.
- Chrome, Edge, Firefox and Safari have it on by default in current versions. In October 2025, Cloudflare reported the majority of human traffic through its network used it.
- Servers are further behind: Cloudflare measured 3.7% of origins in 2025.
- Test your own endpoints with a capable client and read the negotiated group.
- If a hybrid handshake fails, suspect a middlebox that mishandles a ClientHello split across two packets.
- Record the library, version and result for each endpoint, and re-test after upgrades.
Sources
- NIST CSRC: FIPS 203, Module-Lattice-Based Key-Encapsulation Mechanism Standard (13 August 2024)
- IETF: RFC 10024, Post-Quantum Traditional (PQ/T) Hybrid Key Agreement Mechanisms for TLS 1.3 (August 2026)
- Cloudflare: State of the post-quantum Internet in 2025 (October 2025)
- Cloudflare Docs: PQC support (compatibility list)
- Cloudflare Docs: PQC to origin (bssl and OpenSSL checks, ClientHello size)
- OpenSSL: OpenSSL 3.5 final release announcement (April 2025)