In March 2025, Cloudflare measured roughly 38% of HTTPS traffic on its network using hybrid post-quantum key exchange. By the time you finish reading this sentence, your browser has likely completed several TLS handshakes that combined a 1990s-era elliptic curve algorithm with a lattice-based cryptosystem standardized only in 2024. The combination is called X25519MLKEM768, and it has quietly become the default key agreement mechanism on most of the web — not because anyone has built a quantum computer that breaks elliptic curves, but because someone might, eventually, and the encrypted traffic being captured today will still matter when they do.
This article explains why the industry settled on a hybrid construction rather than replacing classical cryptography outright, what X25519MLKEM768 actually does on the wire, where it breaks in practice, and how to verify whether your servers are participating. The picture is messier than vendor announcements suggest.
Why Hybrid, Not Replacement
The threat model driving deployment is harvest now, decrypt later (HNDL): an adversary records encrypted traffic today and stores it until a cryptanalytically relevant quantum computer (CRQC) arrives capable of running Shor’s algorithm against the elliptic-curve Diffie-Hellman exchange that protected the session key. Symmetric ciphers like AES-256 and ChaCha20-Poly1305 remain largely unaffected — Grover’s algorithm only halves their effective security — but the asymmetric key exchange is the entire game. Break that, and the AES-encrypted payload falls open.
NIST finalized ML-KEM (Module-Lattice-based Key Encapsulation Mechanism, formerly Kyber) as FIPS 203 in August 2024, alongside ML-DSA (FIPS 204) for signatures and SLH-DSA (FIPS 205) for hash-based signatures. ML-KEM is the post-quantum replacement for key exchange. But replacing X25519 outright would be reckless. Lattice cryptography is a younger field than elliptic curves, and an unexpected cryptanalytic break — a sufficiently clever attack on the Module-LWE problem underlying ML-KEM — would compromise every connection negotiated with it.
Hybrid construction sidesteps the dilemma. In a hybrid, you still run a familiar classical key exchange like X25519 and add a post-quantum KEM in parallel. The handshake binds both results. If either remains secure, the derived session key remains confidential. An adversary needs to break both primitives to recover plaintext. Cryptographers call this property hybrid composability, and it is the explicit recommendation of NSA’s CNSA 2.0 guidance, the European Union Cybersecurity Certification (EUCC) framework, and the IETF TLS Working Group during the transition window.
What X25519MLKEM768 Actually Does
The IETF draft draft-ietf-tls-ecdhe-mlkem, adopted by the TLS Working Group in March 2025, defines three hybrid named groups for TLS 1.3: X25519MLKEM768, SecP256r1MLKEM768, and SecP384r1MLKEM1024 — combining ML-KEM with ECDH. The first one, X25519MLKEM768, is what virtually every browser ships and what Cloudflare reports as roughly 95% of post-quantum connections it sees.
The mechanics on the wire:
The client sends a ClientHello that advertises X25519MLKEM768 (codepoint 0x11EC) in its supported_groups extension and includes a key_share containing the concatenation of an ML-KEM-768 encapsulation key and an X25519 ephemeral public key. The client share is 1216 bytes: 1184 bytes for the ML-KEM part and 32 bytes for X25519.
The server, if it supports the group, performs the FIPS 203 encapsulation key check on the ML-KEM material, generates an X25519 ephemeral key, and runs ML-KEM encapsulation against the client’s key. It returns a ServerHello containing the ML-KEM ciphertext concatenated with its X25519 share — 1120 bytes total: 1088 bytes for the ML-KEM ciphertext and 32 bytes for X25519.
Both sides now derive a shared secret by concatenating the ML-KEM shared secret (32 bytes) with the X25519 shared secret (32 bytes), producing 64 bytes that feed the TLS 1.3 key schedule. The order matters and is fixed by the draft: ML-KEM first, then X25519.
If the server doesn’t support the group, it picks a classical fallback like plain x25519 or secp256r1, the connection completes without post-quantum protection, and the client has wasted some bandwidth advertising a key share nobody used.
How Adoption Actually Rolled Out
The browser timeline is more compressed than most coverage acknowledged. Chrome shipped the pre-standard X25519Kyber768Draft00 enabled by default in Chrome 124 (April 2024), then switched to the standardized X25519MLKEM768 in Chrome 131 (November 2024). Edge, sharing Chromium, followed the same release. Firefox enabled X25519MLKEM768 by default in Firefox 132 for HTTPS, with QUIC/HTTP3 support arriving in Firefox 135. As of August 2025, both Firefox and Chrome support, enable, and offer X25519MLKEM768 by default. Apple announced that macOS Tahoe 26 and iOS 26 would add support in fall 2025.
Server-side adoption has been less uniform. Cloudflare, Google, and Akamai all support the hybrid group at the edge — Akamai launched browser-to-edge PQC support on Enhanced TLS hostnames on September 1, 2025, with the goal of completing all internal mid-tier connections by Q1 2026. For self-hosted servers, OpenSSL 3.5 (released April 2025) was the first stable release with native ML-KEM support, eliminating the need for the oqsprovider plugin. Java added the X25519MLKEM768 named group to the JDK via JEP 527.
Past the browser-to-CDN boundary, deployment thins. Most Apache, nginx, and HAProxy deployments are still negotiating classical X25519 because the operator hasn’t enabled the post-quantum group, the OpenSSL build is too old, or the load balancer in front silently drops oversized handshakes.
Why Some Connections Still Break
The defining engineering problem of post-quantum TLS is size. A classical X25519 ClientHello fits comfortably in a single TCP segment. A hybrid ClientHello with X25519MLKEM768 adds roughly 1.1 KB and frequently spans two segments. Every middlebox, firewall, IDS, and load balancer that assumed the entire ClientHello would arrive in one packet — and there are many — gets to discover a new failure mode.
The catalog of breakage, documented at tldr.fail and confirmed across vendor bug trackers:
Firewalls and intrusion detection systems reject oversized ClientHello messages. Load balancers with small buffer defaults truncate the handshake. Middleboxes and enterprise proxies cannot parse the larger key shares. Network equipment with small MTU or fragmentation issues cause silent failures.
A representative open issue: HAProxy issue #3148, October 2025, where with OpenSSL 3.5.x clients preferring X25519MLKEM768, a portion of connections to HAProxy-fronted web farms abort with TCP RST or TCP FIN immediately after the ClientHello. The maintainers ultimately classified it as configuration rather than a bug, but the practical effect is the same — connections drop, often non-deterministically, and operators chasing the cause spend hours staring at packet captures.
There is a quieter performance cost on QUIC. Because QUIC’s anti-amplification limit caps server response to 3× the bytes received before address validation, and a hybrid ClientHello is around 1.3 KB while a full PQC certificate chain can run 17 KB, the server may be forced into an extra round trip waiting for the client to ACK. Hybrid TLS over QUIC is correct but not free.
A subtler class of bug appears in cryptographic libraries themselves. In Go 1.24+, X25519MLKEM768 was added to the FIPS-approved curve list, but the underlying crypto/ecdh.X25519 primitive is unconditionally rejected in fips140=only mode, breaking every TLS handshake that attempts the hybrid group under strict FIPS. The bug has been open since March 2026 and reflects an unresolved tension: NIST’s FIPS validation regime hasn’t fully caught up to the hybrid construction, leaving FIPS-mandated environments unable to use the very algorithm regulators are pushing them toward.
Named Groups, Codepoints, and Where They Apply
If you are configuring servers, the relevant identifiers and their use cases:
The pattern matters: X25519MLKEM768 is what you turn on for general traffic. SecP256r1MLKEM768 is what you turn on when a regulator requires every primitive in the chain to be on the FIPS-approved list. The third group, SecP384r1MLKEM1024, is positioned as the long-term CNSA 2.0 target — NSA’s stated timetable for compliant browsers, servers, and services is to exclusively use FIPS 203 at level V (ML-KEM-1024) by 2033.
The Compliance Calendar
Hybrid is officially an interim posture. The U.S. National Security Agency has been clear that the destination is single-encryption ML-KEM, not hybrid; the question is timing. For National Security Systems, all new acquisitions must use NSA-approved quantum-resistant algorithms by 2027 under CNSSP 15, and all NSS must be quantum-resistant by 2035 per NSM-10. CNSA 2.0 sets 2030 for full application migration and 2035 for complete infrastructure migration.
The European posture, expressed through ETSI and the EUCC framework, currently endorses hybrid through at least 2028 and treats single-PQ-only deployments as premature. The FIPS validation regime in the U.S. is in an awkward middle state: ML-KEM is FIPS-approved, X25519 is not, so the strictly-FIPS-compliant hybrid is SecP256r1MLKEM768 rather than X25519MLKEM768 — and Chrome doesn’t ship that one by default.
Browsers reflect the tension. Google has stated that the enterprise policy PostQuantumKeyAgreementEnabled, which let administrators disable the hybrid group during the rollout to work around middlebox breakage, is being phased out: by Chrome 138 (mid-2025) the override no longer disables ML-KEM, with full removal scheduled for 2026.
What to Actually Do
For most organizations operating client-facing TLS, the practical steps are short. Inventory what your servers, load balancers, and CDN configurations actually negotiate — openssl s_client -groups X25519MLKEM768 against a representative sample is sufficient. If the answer is X25519MLKEM768, you are done for client-facing TLS. If it is X25519, find out whether the gap is the OpenSSL version, the load balancer config, or a middlebox dropping oversized ClientHellos.
For internal east-west traffic — service mesh, mTLS between microservices, VPN concentrators — the hybrid is rarely enabled by default. This is the largest unmonitored attack surface for HNDL collection inside enterprise networks, because service-to-service traffic often carries higher-value data than the public-facing edge.
For long-lived data at rest, none of this matters. Hybrid TLS protects the wire. It does not re-encrypt the database backups already on tape, the email archives in S3, or the records in a data lake. Any data with a confidentiality lifetime measured in decades needs a separate plan, and that plan is the harder problem.
FAQ
Is X25519MLKEM768 slower than plain X25519? On modern hardware the additional CPU is negligible — ML-KEM-768 key generation, encapsulation, and decapsulation each run in well under a millisecond. The real cost is bandwidth: roughly 2.3 KB of additional handshake data per connection, which matters at scale and on constrained networks but is invisible on a desktop browser.
Does enabling hybrid break clients that don’t support it? No, if your server is configured correctly. TLS 1.3 group negotiation is graceful — a client that doesn’t advertise X25519MLKEM768 will negotiate a classical group your server also supports. The breakage almost always comes from middleboxes between client and server, not from the negotiation itself.
Why ML-KEM-768 specifically and not 512 or 1024? ML-KEM-768 targets NIST security category 3, roughly equivalent to AES-192. The non-hybrid TLS draft specifies all three parameter sets — ML-KEM-512, ML-KEM-768, and ML-KEM-1024, but 768 was chosen for the hybrid default as the sweet spot of security margin and handshake size. ML-KEM-1024 is the CNSA 2.0 long-term target.
Should I enable single-PQ-only ML-KEM groups now? No. The IETF draft for non-hybrid ML-KEM in TLS exists but is not where the working group is steering deployment, and the EUCC explicitly recommends against it during the transition. The whole point of hybrid is the safety net: an unexpected attack on lattice cryptography would not silently break every TLS connection.
The Stance
X25519MLKEM768 is not an end state. It is a pragmatic compromise that buys time against an adversary nobody has built yet, paid for in handshake bytes and edge-case middlebox failures. The cryptographic engineering is sound; the operational hangover — FIPS-mode bugs in Go, HAProxy configs that drop fragmented ClientHellos, OpenSSL versions that pre-date FIPS 203 — will take years to drain.
The honest deployment posture for 2026: enable the hybrid group on every server you control, watch for connection failures from middleboxes you do not control, and treat the day NSA mandates single-encryption ML-KEM-1024 — currently scheduled for 2033 — as a separate migration to plan for now, not a problem inherited later.






