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 demands | Can complete | Cannot |
| 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.
| Client | Verdict | What 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.