Back to Blog

Post-Quantum TLS in 2026: Why Matching JA4 No Longer Saves the Scraper

Browsers have transitioned to post-quantum key exchange, while most scraping stacks have not. The lack of PQ key share has become a standalone automation marker. We compare Chrome, Go, Node, Python, curl_cffi, and uTLS in terms of readiness and explain how to check your client.

📅September 3, 2026
Post-Quantum TLS in 2026: Why Matching JA4 No Longer Saves the Scraper

A year ago, the scheme was straightforward: you take a client that can spoof the TLS handshake, match a profile to the latest Chrome, get a matching JA4 — and the anti-bot lets it through. By 2026, this recipe started to fail due to a reason that has nothing to do with "bypassing protections." Browsers have widely transitioned to post-quantum key exchange, while most scraping stacks have not. Now, the lack of post-quantum key share is itself a marker of automation.

Let's break it down by criteria: what exactly has changed in the handshake, which stacks have transitioned, which have not, and why a matching JA4 hash is no longer sufficient.

What Happened: Post-Quantum Exchange Became the Norm, Not an Exotic

Hybrid post-quantum key exchange combines the classic elliptic curve X25519 with the lattice-based mechanism ML-KEM (NIST FIPS 203 standard). A session remains secure if at least one of the two components is resilient. The idea is to protect against the scenario of "intercept now, decrypt later," where traffic is archived in anticipation of future quantum computers.

Timeline of implementation in clients:

  • Chrome 124 (April 2024) — hybrid post-quantum exchange is enabled by default; this is noted in curl-impersonate patches as "curves X25519Kyber768/X25519MLKEM introduced in Chrome 124 and 130."
  • Firefox 132 (November 2024) — support is enabled.
  • Safari on iOS and macOS — post-quantum exchange arrived in October 2025.
  • OpenSSL 3.5.0 (April 2025) — hybrid groups X25519MLKEM768, SecP256r1MLKEM768, and SecP384r1MLKEM1024 were added to the default TLS group list.
  • Go 1.24 (February 2025) — X25519MLKEM768 is included in crypto/tls by default unless Config.CurvePreferences is explicitly set.

From the infrastructure side, the picture is even clearer. Cloudflare Radar in April 2026 showed about 67% of human HTTPS traffic with post-quantum encryption — up from 32% in January 2025. Akamai made post-quantum key exchange the default for all client connections on January 31, 2026, completing the rollout across the network in March. According to industry measurements, about 57.4% of all browser transactions are already post-quantum ready, with the share of PQ-capable Chrome around 93%.

Note the asymmetry: support on the origin server side is growing much more slowly (around 9% at Cloudflare). Thus, post-quantum capability today is primarily a characteristic of the client. Exactly what interests the anti-bot.

Criterion 1: Size of Key Share and Structure of ClientHello

The post-quantum key share is not "just another flag in the extension." It is physically large: about 1124 bytes compared to 36 bytes for classic X25519. The consequences are visible to the naked eye at the packet level.

ClientHello with a post-quantum key share exceeds 1400 bytes and can no longer fit into a single TCP segment. It is split into two or more packets. And then the most interesting part for detection begins: the fragmentation pattern varies across different implementations. How exactly the stack slices the large ClientHello, in what order it sends segments, and with what timings — this is observable behavior that is not derived from the JA4 hash and that almost none of the scraping tool authors consciously reproduce.

The practical conclusion: the anti-bot has a layer operating below the familiar fingerprint. You can perfectly compile a list of ciphers and extensions, but you can reveal yourself by how your stack places bytes into the socket.

Criterion 2: Consistency with Declared Browser Version

The main trap of 2026 is the desynchronization between who you claim to be and what your TLS stack is actually doing.

Anti-bot platforms maintain databases of reference ClientHello messages. A request that claims to be Chrome 131 in the User-Agent and JA4 but arrives without a post-quantum key share does not match any known valid Chrome 131. This is not "suspicious" — it is a logically impossible combination. A real Chrome of that version cannot physically send a classic key share with default settings.

How well this is separated by machine learning has also been calculated. The CatBoost classifier on JA4 features shows AUC 0.998 and accuracy 0.9863; separately, post-quantum traffic differs from classic with an accuracy of about 98%. This is not "heuristics with false positives"; it is practically a deterministic feature.

Criterion 3: Readiness of Specific Stacks

This is where the real line of division occurs. Let's break it down into groups.

Send PQ Key Share by Default

  • Chrome 124+, Firefox 132+, Safari (iOS/macOS from October 2025) — the standard against which you are compared.
  • Go 1.24+ — crypto/tls includes X25519MLKEM768 by itself unless you have overridden CurvePreferences. An important nuance: post-quantum capability exists, but JA4 for a bare Go client is still not browser-like. You get a "PQ-compatible, but not resembling Chrome" fingerprint.
  • Node.js 24 — carries its own OpenSSL 3.5, so the default group list already includes hybrid. Plus, ML-KEM has appeared in node:crypto via crypto.encapsulate()/decapsulate() and ML-DSA in sign()/verify().

Depend on What They Are Linked To

  • Python: requests, aiohttp, httpx — use the ssl module, which takes the system's OpenSSL. On Ubuntu 24.04, the system has OpenSSL 3.0.x, where post-quantum groups do not exist at all. To obtain PQ, you need to build OpenSSL 3.5 from source, place it via LD_LIBRARY_PATH, and likely rebuild Python itself. In practice, this means: typical Python scraper in 2026 sends a classic key share and appears as an anomaly on Akamai.

Can Do, But Only If the Right Profile is Selected

  • curl_cffi / curl-impersonate — support for post-quantum curves is present and explicitly stated in the fork. However, the target list ranges from chrome99 to chrome146 (in the fork — up to chrome150), and old profiles reproduce the handshake of their time, meaning without PQ. Copy-pasting impersonate="chrome116" from a two-year-old guide is a direct path to detection.
  • uTLS — the same principle: HelloChrome profiles below 131 do not contain PQ key share. Additionally, the library for 2026 closed two fingerprinting vulnerabilities: CVE-2026-26995 (versions 1.6.0–1.8.1) and CVE-2026-27017 (1.6.0–1.8.0, desynchronization of cipher selection for GREASE ECH — Chrome selects it deterministically, while parrot in uTLS flipped a coin between AES and ChaCha20, which is impossible for real Chrome). You need to update to at least 1.8.2.

The common denominator: tools have mostly caught up. The problem is not with them, but with the fact that configs age faster than browsers. A profile that was ideal in 2024 now works as a marker.

How to Check Your Stack in Five Minutes

  1. Send a request from your production client to https://tls.peet.ws/api/all or ja4db.com — they return live JA3/JA4 and a breakdown of ClientHello in JSON.
  2. Find in the breakdown the list of supported_groups and key_share. Look for X25519MLKEM768 (or X25519Kyber768 in older profiles). If there is only x25519/secp256r1 — there is no post-quantum exchange.
  3. Cross-check this with the browser version you are claiming. If you claim Chrome 131+ and do not see PQ groups — the combination is invalid; fix the profile.
  4. Look at the size of ClientHello. Less than ~1400 bytes when claiming a recent Chrome — the same sign, just from the other side.
  5. Run the check from each exit node, not just from your working machine: SSL inspection on a corporate gateway or by the provider may rewrite the handshake for you.

What Proxies Do Here

It is important not to mix two independent layers. The post-quantum key share is about the handshake, while the reputation of the address is about the network. The anti-bot considers them separately and adds them up.

From this, two practical consequences arise. First: an ideal residential IP will not save a request that at the TLS level claims to be Chrome 131 without a PQ group — you will lose even before the server looks at the address. Second, conversely: a properly constructed post-quantum handshake will not help if hundreds of your sessions come from a single data center subnet with a tarnished reputation. Both layers need fixing, and they are fixed with different tools.

Practical breakdown by tasks: for purposes behind Akamai and Cloudflare, where both the handshake and the network are considered, it makes sense to use residential proxies and simultaneously raise the target impersonate to a recent Chrome. For mobile applications and platforms where IP reputation weighs more than TLS requirements, mobile proxies often win. And for your own APIs, partner exports, and internal monitoring, where there is no anti-bot, it makes no sense to overpay for residential — data center proxies will suffice.

If you are starting from scratch with fingerprinting, begin with the basics: how JA4 works and what it includes. And when it comes to not just an HTTP client but a full-fledged browser, the comparison of stealth builds and their weak points is compiled separately — nodriver, Camoufox, and Patchright in 2026 benchmarks.

Conclusion

Post-quantum key exchange was not conceived as an anti-bot mechanism. It has become one incidentally: browsers transitioned to it quickly and en masse, infrastructure (Akamai — since January 31, 2026) made it the default, and scraping stacks split into three groups — those that have transitioned, those dependent on system OpenSSL, and those that can only do so with a fresh profile.

Checking boils down to one question: does your client send X25519MLKEM768 and is this consistent with the browser version you claim to be using? If not — a matching JA4 will not save you, because they are comparing not just the hash, but the entire form of the handshake: the size of the key share, the number of TCP segments, and the order in which they are sent. The good news is that in most cases, this can be fixed by updating the profile and library version, rather than rewriting the scraper.