checkfleet

Post-quantum TLS readiness check

pq — Post-quantum TLS readiness

Which classes of TLS client can still handshake — and whether the others are declined with an alert or cut off mid-hello, which is the difference between a setting and an outage.

checkfleet check pq --config checkfleet.yml

Which classes of TLS client can still complete a handshake with an endpoint, now that hybrid post-quantum key exchange (X25519MLKEM768) is on by default in Chrome, Edge, Firefox, Go 1.24+, OpenSSL 3.5+ and several CDNs. It embeds pqprobe rather than reimplementing it: the distinction the check rests on has to live in one place.

That distinction is the point of the module. A peer that answers a post-quantum ClientHello with a TLS alert parsed it and declined a group — a policy, a pinned group list, a negotiation that worked. A peer that resets, times out or vanishes choked on the hello itself, and is broken for every client that so much as offers ML-KEM, however happy that client would have been with X25519. Only the second is an outage waiting for a CDN to flip a default, and no other check here reports the difference.

  • pq-readyOK: hybrid key exchange works, including for a client that requires it.
  • pq-blindWARN: no ML-KEM, but capable clients still connect on a classical group.
  • pq-refusingBAD: capable clients are declined with an alert while classical ones connect — look at the configuration.
  • pq-intolerantBAD: capable clients are cut off while classical ones connect — look at the path: a middlebox, an old TLS library, a load balancer that reads the hello.
  • no-tls13WARN: TLS 1.2 is the ceiling, so post-quantum is out of reach; a ceiling, not a setting.
  • unreachable / tls-broken / mtls-requiredERROR: not a grade at all.

A healthy endpoint is one row. A failing one keeps its evidence: the verdict plus the handshake that produced it, which together are the argument somebody takes to a CDN vendor.

Targets accept the same forms pqprobe does, including 1.2.3.4=origin.example to dial an address while sending a server name — the only way to reproduce a CDN-only failure from here, and the way to find the one node out of six that is broken.

Read-only: TLS handshakes, closed immediately. No request, no body, no credentials — there is nothing it could change on the far side.

See Configuration → checks.pq.


See the full module reference for every check, or configuration for the config keys.