PQ Crypta Logo

Post-quantum certificates are the half nobody is ready for

8 of 12 implementations complete a hybrid key exchange. 3 can receive a post-quantum certificate.

PQ CRYPTA PLATFORM

🏠 Main

🧪 Interactive Apps

📰 News

🛡️ PQ Crypta Proxy

👤 Account

⟨ QUANTUM ERROR PORTAL ⟩

Navigate the Error Dimensions

Post-quantum migration is usually discussed as one thing. It is two, and the measurements below put them a long way apart. Key exchange is nearly done. Certificates have barely started, and no amount of server configuration moves them.

Measured on 2026-09-18T00:44:57Z by driving each client's own binary against ports that serve exactly one thing. Every count on this page is read from that run rather than written into it.

The two halves, side by side

What the port demandsCan completeCannot
X25519MLKEM768 key exchange only 8 of 12 curl, aioquic, xquic, msquic
ML-DSA-87 certificate chain 3 of 12 curl, quinn, aioquic, chromium, quic-go, quiche, picoquic, lsquic, msquic

Both ports are legal configurations. Neither emits a malformed byte: one negotiates a single key exchange group, the other serves a certificate chain signed with a post-quantum algorithm. What is measured is what a client does when the thing it expected is not on offer.

Why the certificate half is harder

A hybrid key exchange is a negotiation. Both ends offer what they have, and a client that supports X25519MLKEM768 uses it while one that does not falls back — so a server can enable it unilaterally and lose almost nobody. That is why 8 of 12 implementations complete a handshake against a port that will speak nothing else.

A certificate is not a negotiation in the same sense. The client sends signature_algorithms listing what it can verify, and a server holding only an ML-DSA-87 chain against a client that does not name ML-DSA-87 has nothing to send. The handshake fails on the server side, before the certificate goes out, with no useful signal to the operator beyond a failed connection.

That asymmetry is the finding. Hybrid key exchange can be turned on today and almost everything still connects. A post-quantum certificate cannot be turned on at all for most of these clients, and the failure will look like the server is broken.

What each client did with the chain

The chain is issued by a private CA on purpose, and being untrusted is what makes the measurement work. A client that rejects it over trust has already decompressed 55 KB of certificate, parsed ML-DSA-87 structures it may never have seen, and got as far as chain building. Rejecting an unknown CA after all that is correct behaviour, and it demonstrates exactly the capability under test.

ClientVerdictWhat happened
curl Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.
quinn Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.
aioquic Not run Not attempted.
chromium Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.
quic-go Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.
quiche Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.
neqo Pass Handled it: completed the handshake against an ML-DSA-87 chain: the compressed certificate message was decompressed, the chain parsed, and a post-quantum signature verified. Note that a client run with certificate verification disabled reaches this point without trusting anything, so what this shows is that the chain was processed, not that it was trusted.
picoquic Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.
ngtcp2 Pass Handled it: completed the handshake against an ML-DSA-87 chain: the compressed certificate message was decompressed, the chain parsed, and a post-quantum signature verified. Note that a client run with certificate verification disabled reaches this point without trusting anything, so what this shows is that the chain was processed, not that it was trusted.
lsquic Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.
xquic Pass Handled it: aborted over the certificate with TLS alert 40. Reported rather than graded: RFC 8879 §4 lets a receiver cap the decompressed size and abort, and no document requires ML-DSA support of anyone.
msquic Inconclusive The run did not exercise this test: the client's signature_algorithms named nothing that can verify an ML-DSA-87 chain, so this endpoint refused before sending one. Post-quantum certificates are not reachable for this client at all, which is a fact about it rather than a gap in the run.

What this does not say

Nothing here is a defect report. No RFC requires support for ML-DSA certificates, RFC 8879 certificate compression is optional, and its §4 expressly lets a receiver cap the decompressed size and abort. A client that cannot receive this chain is not violating anything, and the test is classed discretionary so that it is never scored as though it were.

What the page claims is narrower and more useful: at the date of this run, an operator who turns on post-quantum certificates will be unreachable to most of these stacks, and will get no clearer diagnosis than a handshake that failed. That is worth knowing before the deadlines arrive, not after.

Full results: the matrix, this test across every client, and every failure grouped by clause. Citations: RFC 8879 §4, RFC 8446 §4.4.2.