JA3 vs JA4: TLS Fingerprinting for Bot Detection in 2026

JA3 broke when Chrome 110 shuffled ClientHello order. How JA4 and JA4+ work, which anti-bot vendors adopted them, and what it means for automation in 2026.

VoidMob Team
15 min read
JA3 versus JA4 TLS fingerprinting comparison for bot detection

In early 2023, Chrome 110 shipped a small RFC-driven change that quietly destroyed the most widely used bot detection signal on the internet: extension order randomization in the ClientHello. Every JA3 hash generated by a real Chrome browser became unique per session, just like that. Anti-bot vendors who'd spent years building blocklists around JA3 fingerprints watched their signal-to-noise ratio fall apart overnight.

By 2026, the migration from JA3 to JA4 is essentially done across every major anti-bot platform. But here's the thing most guides miss: they cover JA3 vs JA4, stop at the TLS layer, and completely ignore the three other detection layers that actually determine whether a session gets flagged.

Quick Summary TLDR

  • 1JA3 hashed five ClientHello fields into a single MD5 string. Chrome 110 broke it by randomizing extension order.
  • 2JA4 replaced it with a structured, human-readable format that sorts internal lists before hashing, making it resilient to shuffling.
  • 3In 2026, Cloudflare, DataDome, Akamai, Imperva, and F5 all run JA4 or the broader JA4+ suite in production.
  • 4TLS fingerprinting is only one of four layers that get checked: TCP/IP (p0f), TLS (JA4), DNS ASN alignment, and HTTP behavioral coherence.
  • 5curl_cffi closes the JA4 gap for HTTP clients, but Playwright, Puppeteer, and Selenium still leak distinguishable fingerprints without patching.

What JA3 Was and Why It Worked So Well

JA3 launched in 2017 via a Salesforce Engineering blog post authored by John Althouse, Jeff Atkinson, and Josh Atkins. The concept was beautifully simple: grab five fields from the TLS ClientHello message (TLS version, cipher suites, extensions, elliptic curves, and elliptic curve point formats), concatenate them in order, and hash the result with MD5.

One string. 32 hex characters. That was the entire JA3 fingerprint.

It worked because every TLS client implementation produced a deterministic ClientHello. Python's requests library (built on urllib3) always generated the same JA3 hash. So did httpx. So did every default Go HTTP client, every Node.js https module, and every unpatched Selenium instance. Anti-bot vendors could maintain relatively small blocklists of known automation JA3 hashes and catch a large share of bot traffic with minimal effort.

Cloudflare, DataDome, Akamai, and Imperva all integrated JA3 fingerprinting into their detection stacks. It was portable, easy to implement, and had a low false positive rate because real browsers produced consistent, known-good hashes. For about six years, JA3 was the de facto standard for TLS fingerprint bot detection. Nothing else came close.

"JA3 worked for six years because every automation library produced the same deterministic ClientHello. One hash, one blocklist entry, millions of bots caught."

How Chrome 110 Broke JA3

January 2023. Chrome 110 rolled out TLS extension permutation, randomizing the order of extensions in the ClientHello on every new connection. Google's motivation had nothing to do with anti-bot; it was an IETF-aligned change meant to prevent ecosystem ossification, so middleboxes wouldn't hardcode assumptions about extension ordering. Reasonable goal, honestly.

The side effect was devastating for JA3-based detection though.

Since JA3 hashed extensions in their original order, a single Chrome installation now produced a different JA3 hash on every session. Real browser traffic became indistinguishable from randomized bot traffic at the JA3 level.

And impersonation libraries caught up fast. Tools built on the curl-impersonate approach, and later curl_cffi, could reproduce any target JA3 hash by specifying a browser impersonation preset. When defenders can't maintain a stable allowlist for real Chrome, and attackers can spoof any JA3 hash trivially, the signal is dead.

By mid-2024, JA3 as a standalone detection signal was effectively useless for modern browser identification. Some vendors kept logging it alongside newer signals, but nobody was making blocking decisions based on JA3 alone anymore.

Loading chart...

What JA4 Does Differently

JA4 was developed by John Althouse, the same author as JA3, through his company FoxIO. The fix for the extension shuffling problem comes down to one design choice: sorting.

Instead of hashing fields in their original order, JA4 sorts cipher suites, extensions, and signature algorithms before hashing. Regardless of how Chrome shuffles its ClientHello extensions, the resulting JA4 fingerprint stays identical. That's the core insight, and it's documented in full in FoxIO's open-source JA4 repository.

The format itself is also completely different from JA3. Where JA3 produced a single opaque MD5 hash, JA4 uses a human-readable structured string split into three sections:

t13d1516h2_8daaf6152771_b186095e22b6

  • Section A: protocol (TCP/QUIC), TLS version, SNI presence, cipher count, extension count, and the first ALPN value, all in plain characters
  • Section B: truncated SHA256 of the sorted cipher suite list
  • Section C: truncated SHA256 of the sorted extension list plus signature algorithms
ja3-vs-ja4-output.txtplaintext
JA3 output:  e7d705a3286e19ea42f587b344ee6865
JA4 output:  t13d1516h2_8daaf6152771_b186095e22b6

JA3 = opaque MD5, order-dependent
JA4 = structured, human-readable, order-independent

A Chrome 131 browser produces the same JA4 hash whether it shuffles extensions or not. That's why JA4 survives where JA3 failed.

FeatureJA3JA4
Hash algorithmMD5SHA256 (truncated)
FormatSingle opaque stringThree-section structured string
Extension order sensitiveYesNo (sorted before hashing)
Human readable
Chrome 110+ compatibleBrokenFully functional
Maintained byLegacy (Salesforce, 2017)FoxIO (active development)
LicenseOpen, no restrictionsBSD 3-Clause (JA4 core)

The JA4+ Suite: JA4 Is One Piece of a Larger Family

JA4 (the TLS client fingerprint) gets most of the attention, but FoxIO maintains it as part of a broader JA4+ suite that fingerprints traffic at nearly every layer of the stack, not just TLS. Each member follows the same design principle: sort before hashing, output a structured string instead of an opaque hash.

  • JA4 – TLS client fingerprint (what this guide focuses on)
  • JA4S – TLS server response fingerprint, used to identify which server software or CDN is answering
  • JA4H – HTTP client fingerprint, derived from header order, casing, and values rather than TLS
  • JA4L – lightweight latency-based distance metric between client and server
  • JA4X – X.509 certificate fingerprint, useful for fingerprinting client certificates and mTLS setups
  • JA4SSH – SSH client and server fingerprint
  • JA4T – TCP client fingerprint, computed from window size, options, and MSS before any TLS handshake even starts

JA4 itself is released under a permissive BSD 3-Clause license with no patent claims, which is a large part of why adoption moved so fast. The rest of the JA4+ family carries FoxIO's own license terms that permit internal and research use but require a commercial license for OEM integration into paid products. Anti-bot vendors selling detection-as-a-service fall into that second bucket, which is one reason JA4 adoption announcements from Cloudflare, Akamai, and AWS all cite formal licensing arrangements rather than just pulling the open-source spec.

Why JA4T matters alongside JA4

JA4T fingerprints the TCP handshake itself, the same layer that p0f-style OS detection has used for over two decades. A connection can have a perfect JA4 (TLS) hash and still get flagged if JA4T reveals a Linux TCP stack behind a request claiming to be an iPhone. TLS-layer and TCP-layer fingerprints get scored together, not independently.


Which Anti-Bot Vendors Migrated to JA4+ in 2026

The migration is effectively complete across the major platforms:

Cloudflare exposes JA3 and JA4 fingerprints as native fields for Bot Management customers. Cloudflare computes the fingerprint directly from the TLS handshake it terminates, so a client cannot forge or inject a fake value the way it can with a header. Independent 2026 bot detection research puts Cloudflare's daily JA4 fingerprint volume in the tens of millions, correlated against claimed browser identity at request time.

DataDome folds JA4 into its server-side signal stack alongside p0f-style TCP/IP fingerprinting and HTTP/2 frame analysis, feeding all of it into a continuously recalculating trust score rather than a static allowlist.

Akamai uses JA3/JA4 as one layer inside Bot Manager, chained with sensor payload verification and device fingerprint consistency checks, matching how FingerprintJS describes modern detection as inherently multi-layered rather than any single signal.

Imperva and F5 have both added JA4+ support to their respective bot management and WAF products, following the same industry pattern of moving detection weight from client-side JavaScript signals (which evasive bots have optimized against for years) toward server-side TLS and TCP signals that are harder to spoof consistently across an entire session.

Even CDN infrastructure outside the dedicated anti-bot vendors picked it up. Amazon CloudFront added native JA4 fingerprinting support at the WAF layer, which means JA4 now shows up as a detection input well beyond the companies that specialize in bot management.


How to Test Your Own JA4 Fingerprint

Before assuming a client is or isn't JA4-consistent, check it directly. A handful of free tools expose the raw fingerprint a connection produces:

  • tls.peet.ws returns the full TLS and HTTP/2 fingerprint (JA3, JA4, and Akamai's HTTP/2 fingerprint) for whatever client makes the request, which makes it the fastest way to check what a script or library is actually sending.
  • browserleaks.com/tls shows the same data in a browser-friendly format, useful for confirming what a real browser session looks like as a baseline.
  • ja4db.com maintains a lookup database mapping known JA4 hashes to the applications and browser versions that produce them.

Cross-reference more than one tool before drawing conclusions. Implementations vary slightly in how they parse and format the output, and a hash that looks anomalous on one tool sometimes matches a known-good entry on another. For a browser-level check that goes beyond TLS (canvas, fonts, WebGL, and the dozens of other signals that get evaluated alongside a TLS fingerprint), VoidMob's fingerprint test covers the client-side surface that JA4 alone doesn't touch.


Automation Implications: What Breaks and What Doesn't

This is where most JA3-vs-JA4 explainers stop short. Knowing the mechanism doesn't tell you which tools in your stack are already JA4-consistent and which ones are quietly leaking a fingerprint that doesn't match the browser identity they claim.

Do TLS-impersonating HTTP clients solve JA4?

curl_cffi (Python) and the broader curl-impersonate lineage now ship browser impersonation presets that reproduce JA4-consistent handshakes for current Chrome, Edge, and Safari versions. This closes the gap for pure HTTP workflows, API scraping, and anything that doesn't need a real rendering engine. Stock requests, httpx, and urllib3 still produce their own static, easily-identified JA4 hashes with zero browser resemblance.

Do Playwright and Puppeteer leak a TLS fingerprint?

Playwright and Puppeteer drive real Chromium under the hood, so the TLS stack is genuinely Chromium's, which sounds like it should solve JA4 automatically. In practice both still leak distinguishing signals elsewhere (navigator.webdriver, CDP artifacts, automation-specific runtime flags) that anti-bot platforms cross-reference against the JA4 hash. A connection can present a perfectly normal Chrome JA4 fingerprint and still get flagged because the JavaScript-visible automation markers contradict it. Selenium WebDriver has the same problem, plus its own long-documented chromedriver fingerprints.

What about patched browser engines like Nodriver and Patchright?

Nodriver, Patchright (a patched Playwright fork), and SeleniumBase's UC Mode address this at the engine level rather than the network level: they strip or spoof the automation-specific markers that make a technically-correct JA4 fingerprint irrelevant. These are engine patches, not proxy features, and they solve a different problem than anything at the IP or DNS layer.

Node.js and Go

Neither ecosystem ships a browser-matching TLS stack by default. Reproducing a real Chrome JA4 fingerprint from Node.js or Go requires a purpose-built TLS library, such as utls in Go (which explicitly re-implements Chrome/Firefox ClientHello construction) or an equivalent low-level TLS override in Node. Without one, the default runtime TLS implementation in either language produces a static, generic fingerprint that's trivial to flag.

The pattern across all of these: JA4 consistency is a client-side and browser-engine problem. No proxy, IP type, or network configuration changes what TLS library actually constructs the ClientHello.


Where Mobile Proxies Fit (and Where They Don't)

It's worth being direct about this, because a lot of content in this space blurs the line: TLS fingerprinting is a client-side problem, and mobile proxies do not fix JA4 detection on their own. That requires a patched browser engine or a TLS-impersonating HTTP client, full stop. No amount of IP quality changes what bytes go into a ClientHello.

What mobile proxies solve is the layer underneath TLS: IP reputation and ASN classification, the TCP/IP fingerprint at the SYN packet level (the same p0f-style OS detection that JA4T formalizes), and DNS resolver alignment with the IP's carrier ASN. Those are real, separate detection layers, and getting them wrong flags a session just as fast as a bad JA4 hash does, independent of how clean the TLS layer is. VoidMob's breakdown of TCP/IP fingerprinting covers that layer specifically, including why most proxy setups leak a Linux TCP signature underneath a Windows or iOS browser claim.

VoidMob's dedicated proxy tier offers configurable p0f TCP/IP fingerprint matching, which pairs with a JA4-consistent browser or impersonation client for coherent stack presentation from TCP through TLS through HTTP. That's the extent of the relationship: proxy infrastructure handles the network layer, the browser or HTTP client handles TLS, and neither substitutes for the other.

Intended use

This detection-mechanics knowledge is for legitimate work: authorized data collection, QA and pre-release testing, and security research on infrastructure you're permitted to test. It is not appropriate for fraud, credential abuse, engagement manipulation, or any activity that violates a target platform's Terms of Service.


FAQ

1Is JA3 completely dead in 2026?

As a standalone blocking signal, yes. Chrome's extension shuffling since version 110 means real browsers no longer produce a stable JA3 hash, so vendors can't build reliable allowlists around it anymore. Some platforms still log JA3 alongside JA4 for historical correlation, but blocking decisions in 2026 run on JA4 and the broader JA4+ suite.

2Can JA4 be spoofed the same way JA3 was?

Partially. Tools like curl_cffi can reproduce a target JA4 hash for HTTP-only clients because JA4 is still computed from a ClientHello that any TLS library can construct. The harder problem is coherence: a spoofed JA4 hash that doesn't match the TCP fingerprint, DNS resolver, or browser-level signals underneath it is itself a detection signal.

3Does switching to a mobile proxy fix JA4 fingerprint detection?

No. JA4 is computed from the TLS ClientHello, which is generated by the browser or HTTP client, not the network path. A mobile proxy changes the IP, ASN, and (with the right provider) the TCP/IP fingerprint underneath the connection, but it has no effect on what TLS library constructs the handshake above it.

4Which JA4+ suite member matters most for bot detection specifically?

JA4 (TLS) and JA4T (TCP) are the two anti-bot vendors lean on most heavily, because they're both available before a single byte of the actual HTTP request is processed. JA4H (HTTP fingerprint) is a close third, since header order and casing are easy to get wrong in custom HTTP clients.

5Do I need to worry about JA4 if I'm only using Playwright or Puppeteer?

The TLS layer itself is usually fine since both drive real Chromium. The risk is everything else automation frameworks leave behind: navigator.webdriver, CDP-specific runtime artifacts, and timing patterns that get cross-referenced against the JA4 hash. A normal-looking JA4 fingerprint next to obvious automation markers is itself inconsistent, which is exactly the kind of mismatch modern detection stacks are built to catch.


The Practical Takeaway

JA3 is legacy. Anyone still blocking or spoofing based on JA3 alone in 2026 is working against a signal the industry stopped relying on years ago. JA4 and the JA4+ suite are the current standard, and every major anti-bot vendor (Cloudflare, DataDome, Akamai, Imperva, F5) has adopted at least the core JA4 fingerprint into production scoring.

For anything running against Cloudflare, DataDome, Akamai, or similar detection stacks, TLS fingerprint coherence (JA4) plus TCP/IP fingerprint coherence (p0f/JA4T) plus DNS/ASN coherence plus HTTP behavioral coherence is the full stack that gets evaluated. Missing any single layer is what gets a session flagged, no matter how clean the other three look. A JA4-consistent browser on a datacenter IP with mismatched DNS fails just as fast as a perfect mobile IP running stock requests.