All articles
tls fingerprintingJA3JA4

JA4+ TLS Fingerprinting: What Changed in 2026 and Why JA3 Is No Longer Enough

JL
James Liu
Lead Engineer @ ProxyLabs
March 16, 2026
14 min read
Share

TLS fingerprinting isn't a new concept, but the landscape in 2026 has shifted so significantly that the tools we used two years ago are now mostly obsolete. If you are still relying on JA3 to identify or mimic clients, you are likely failing at the edge before your request even hits an application server.

The shift from JA3 to JA4+ represents more than just a version bump. It is a fundamental change in how we approach network-level identity. As browsers have become more aggressive in their privacy measures, anti-bot systems have moved deeper into the protocol stack to find stable signals.

Why JA3 Stopped Being Reliable

JA3 was the gold standard for TLS fingerprinting since its release by Salesforce in 2017. It worked by concatenating five specific fields from the ClientHello packet: TLS Version, Cipher Suites, Extensions, Elliptic Curves, and Elliptic Curve Point Formats.

The result looked like this: 771,4865-4866-4867-49195-...,0-23-65281-10-11-35-16-5-13-51-45-43-27-17513,...,29-23-24,0

This string would then be MD5 hashed to create a 32-character fingerprint. For years, this was enough. A specific version of Chrome on a specific OS would consistently produce the same JA3 hash.

However, the "JA3 churn" started becoming a major problem around 2024. Google Chrome, in an effort to reduce fingerprinting surface area, began randomizing the order of extensions in the ClientHello. Because JA3 relies on the exact order of extensions in its concatenated string, a single browser would now generate thousands of different JA3 hashes.

If the order of extensions changes, the hash changes. This made JA3 "brittle." Anti-bot systems could no longer rely on a static list of "good" JA3 hashes because the same legitimate browser was now sending a different hash with every session.

JA3 Anatomy: The Original Blueprint

To understand why JA4 is better, we need to look at the structure of JA3 more closely. The original fingerprint was a hash of these five fields:

  1. TLS Version: The version of TLS the client wants to use (e.g., 771 for TLS 1.2, 772 for TLS 1.3).
  2. Cipher Suites: A list of encryption algorithms the client supports.
  3. Extensions: A list of TLS extensions the client is requesting.
  4. Elliptic Curves (Named Groups): The curves supported for key exchange.
  5. Elliptic Curve Point Formats: The formats for the curve points.

The core issue was that JA3 didn't account for the evolution of the TLS handshake. It treated the list of extensions as an ordered sequence. When browsers started shuffling that sequence to prevent "ossification" (where servers expect a specific order and break if it changes), JA3's utility plummeted.

JA4: The 2026 Standard

FoxIO introduced JA4 to solve the randomization problem while providing a much more readable and modular fingerprinting system. JA4 isn't just one hash; it's a suite of fingerprints covering different layers of the connection.

The primary client TLS fingerprint, JA4, is divided into three parts: A, B, and C.

Part A: The Transport and Protocol Metadata

Part A is a 10-character string that summarizes the high-level characteristics of the connection. It doesn't use hashing, making it human-readable.

Format: [Protocol][TLS Version][SNI][Cipher Count][Extension Count][ALPN]

  • Protocol: q for QUIC (HTTP/3) or t for TCP.
  • TLS Version: A character representing the version (e.g., 13 for 1.3).
  • SNI: d if a domain is present in the Server Name Indication, i if it's an IP address, or x if empty.
  • Cipher Count: Two digits for the number of cipher suites.
  • Extension Count: Two digits for the number of extensions.
  • ALPN: The first two characters of the first Application-Layer Protocol Negotiation value (e.g., h2 for HTTP/2).

Example Part A: t13d1516h2 This tells us the client is using TCP, TLS 1.3, a domain-based SNI, has 15 ciphers, 16 extensions, and wants to use HTTP/2.

Part B: The Sorted Cipher Suites

Part B is the truncated SHA256 hash (first 12 characters) of the cipher suite IDs, sorted in numerical order. By sorting the ciphers before hashing, JA4 eliminates the randomization issue that killed JA3.

Part C: The Sorted Extensions and Algorithms

Part C is the truncated SHA256 hash (first 12 characters) of the extension IDs and signature algorithms, also sorted in numerical order.

The full JA4 fingerprint is the combination of these three parts: t13d1516h2_8daaf6152771_b1ff8ab2d16f

This multi-part structure allows security systems to be more flexible. They can flag a request if Part B and C look like Chrome but Part A says it's not using a domain-based SNI (which would be highly unusual for a browser).

JA4H: Fingerprinting the HTTP Layer

One of the most powerful additions in the JA4+ suite is JA4H, which moves the fingerprinting from the TLS layer to the HTTP layer. Most developers focusing on "bypass" only look at TLS, but JA4H is where most modern bot detection happens in 2026.

JA4H fingerprints the HTTP request itself. It looks at:

  • Method: ge (GET), po (POST), etc.
  • Version: 11 (HTTP/1.1), 20 (HTTP/2), 30 (HTTP/3).
  • Cookie Presence: c if cookies are present, n if not.
  • Referer: r if a referer header is present, n if not.
  • Header Count: The number of headers in the request.
  • Accept-Language: The first two characters of the language header (e.g., en).

Example JA4H: ge20cn10en_abc123..._def456...

Anti-bot systems use JA4H to catch "impossible" configurations. For example, if your JA4 fingerprint says you are Chrome 124 (which defaults to HTTP/3 or HTTP/2), but your JA4H says you are using HTTP/1.1, you are immediately flagged. Python's requests library is notorious for this—it defaults to HTTP/1.1 and has a completely different header signature than a real browser.

TLS Greasing: The Intentional Noise

If you look at a raw TLS ClientHello from a modern browser, you'll see strange values like 0x0a0a or 0x7a7a in the extension list. These are "GREASE" (Generate Random Extensions And Sustain Extensibility) values, defined in RFC 8701.

Browsers insert these random values to ensure that servers don't write buggy code that assumes a specific extension will always be at a specific position. If your TLS library (like standard OpenSSL or Go's crypto/tls) does not include these GREASE values, you are sending a massive signal that you are a bot.

In 2026, missing GREASE is an instant fail for Cloudflare and DataDome. Legitimate browsers always grease.

HTTP/2 SETTINGS and WINDOW_UPDATE

Beyond the headers and the TLS handshake, there is a third layer of fingerprinting: the HTTP/2 connection parameters. When an H2 connection is established, the client and server exchange SETTINGS frames.

Chrome has a very specific set of default settings:

  • HEADER_TABLE_SIZE: 65536
  • ENABLE_PUSH: 0
  • INITIAL_WINDOW_SIZE: 6291456
  • MAX_HEADER_LIST_SIZE: 262144

Firefox uses entirely different values. If you claim to be Chrome in your User-Agent but your HTTP/2 SETTINGS frame says INITIAL_WINDOW_SIZE: 65535 (the default for many libraries), you are caught.

Furthermore, Chrome sends a WINDOW_UPDATE frame immediately after the handshake with a very distinctive increment value: 15663105. Most HTTP clients don't do this, or they use a round number. This single frame is often enough to differentiate a real browser from a library like httpx or axios.

The Consistency Requirement

The biggest mistake in 2026 is focusing on one fingerprint while ignoring the others. Modern anti-bot systems use a "Consistency Score." They check if all signals agree with each other.

To pass, all of these must align:

  1. JA4: Must match the TLS signature of the claimed browser version.
  2. JA4H: Must match the HTTP signature (headers, order, case) of that browser.
  3. User-Agent: Must be an exact match for the profile being mimicked.
  4. Client Hints (Sec-Ch-Ua): Must be consistent with the User-Agent.
  5. H2 Settings: Must match the browser's internal defaults.
  6. TLS Greasing: Must be present if the UA is Chrome or Edge.

If you send a Chrome 124 User-Agent but your JA4 matches Chrome 110, or your H2 settings are the defaults for the Go h2 package, your consistency score drops, and you get a CAPTCHA or a 403.

How Anti-Bots Use These Signals in 2026

Cloudflare

Cloudflare uses a weighted system. JA4 is a major component, but they also look at behavioral signals. If they see a "perfect" JA4 fingerprint but the request is coming from a datacenter IP with no history, they will still flag it. They use JA4 to group "families" of bots. If one bot with a specific JA4 is caught scraping, all other bots with that same JA4 are scrutinized more heavily.

DataDome

DataDome focuses heavily on the HTTP layer and JA4H. They are particularly good at catching discrepancies between the TLS handshake and the subsequent HTTP request. They look for header ordering and the presence of specific browser-only headers that most libraries omit.

Akamai

Akamai uses a multi-hash approach similar to JA4 but with their own proprietary enhancements. They track the "velocity" of fingerprints across their entire network. If a single JA4 fingerprint is seen across 10,000 different IPs in 5 minutes, it's flagged as a bot farm, regardless of how "real" the TLS handshake looks.

JA4S and JA4L: The Server and Network Signals

The JA4+ suite extends beyond just the client-side TLS handshake. To get a complete picture of a connection, anti-bot systems also look at the server's response and the network latency.

JA4S: The Server Response Fingerprint

JA4S fingerprints the ServerHello message. While you might think you only control the client, the way a server responds to your specific ClientHello is a unique signal. If a "Chrome" client connects to a server and the server responds with a specific set of ciphers and extensions that it only uses for "Python" clients, that discrepancy is a red flag.

Anti-bot systems like Cloudflare use JA4S to verify that the handshake negotiation followed a "natural" path. They look for the intersection of what the client offered and what the server accepted.

JA4L: The Latency Fingerprint

JA4L is one of the most difficult signals to spoof because it's based on physics. It measures the time difference between various steps in the handshake (e.g., the time between the TCP SYN and the TLS ClientHello).

In 2026, bot detection systems use JA4L to detect the presence of "man-in-the-middle" proxies or automated scripts that process packets with a different timing profile than a real browser's networking stack. If your JA4L indicates a multi-hop proxy chain while your IP claims to be a local residential user, your request will be scrutinized.

JA4X: Fingerprinting the X.509 Certificate

When a client performs a handshake, it often validates the server's certificate. JA4X fingerprints the certificate itself and how the client interacts with it. This is particularly useful for identifying automated tools that use hardcoded or custom root CA stores. If a tool doesn't support modern certificate extensions or uses a non-standard validation path, JA4X will reveal it.

The Role of QUIC and HTTP/3 in 2026

By 2026, over 70% of browser traffic uses HTTP/3 (QUIC) rather than traditional TCP. This adds a new layer of complexity to fingerprinting. QUIC moves the encryption and stream management into a single UDP-based protocol.

JA4 handles this with the q prefix in Part A. Fingerprinting QUIC is significantly harder than TCP because many of the signals are encrypted earlier in the handshake. However, this also means that if you are still using TCP (the t prefix) for all your requests, you are standing out from the crowd of real users who have already migrated to QUIC.

A high-quality scraping setup in 2026 must support QUIC and correctly implement the JA4-Q fingerprint. Libraries like tls-client have evolved to include QUIC profiles that mimic the UDP-based handshakes of Chrome and Safari.

Deep Dive: The TLS Extensions That Give You Away

While Part C of the JA4 fingerprint hashes the extensions, some specific extensions are more important than others for detection.

The PSK (Pre-Shared Key) Extension

In TLS 1.3, the PSK extension is used for session resumption. Chrome has a very specific way of formatting its PSK "binders" and "identities." If your library sends a PSK extension that is formatted like an older version of OpenSSL, you are easily identified.

The Application-Layer Protocol Negotiation (ALPN)

As mentioned in Part A, the ALPN is a critical signal. Browsers typically offer h2 and http/1.1. If you only offer http/1.1, or if you offer h3 but don't actually support the QUIC transport, you are sending a contradictory signal.

Signature Algorithms

The list of signature algorithms (e.g., ecdsa_secp256r1_sha256, rsa_pss_rsae_sha256) is another sorted component of Part C. Browsers have a very specific set of supported algorithms that changes with almost every major version. Keeping this list up to date is essential for maintaining a valid JA4 fingerprint.

Advanced Mimicry: Beyond the Handshake

Once you have perfected your JA4 and JA4H fingerprints, you must ensure that your post-handshake behavior is also consistent.

Header Case and Ordering

Even if your JA4H Part A matches, the way you format your headers matters. Most modern browsers use lowercase headers for HTTP/2 and HTTP/3 (e.g., user-agent instead of User-Agent). They also follow a very specific order: pseudo-headers (:method, :path, :scheme, :authority) come first, followed by the others in a predictable sequence.

Compression Algorithms (Brotli and Zstd)

By 2026, zstd has become a common compression algorithm alongside br (Brotli) and gzip. If your accept-encoding header claims you support zstd but your client fails to decode the response, you'll be flagged as a bot on the next request.

Tools to Inspect Your Fingerprint

Before you start scraping, you need to know what you look like to the server.

  • tls.browserleaks.com: A great first stop to see your JA3 and JA4 fingerprints in a human-readable way.
  • tls.peet.ws: Provides an incredibly detailed breakdown of the TLS ClientHello, including the raw bytes and extension order.
  • Wireshark: If you want to see exactly what your code is sending, use Wireshark with the ssl.handshake.type == 1 filter to inspect the ClientHello. Look for the GREASE values and extension order.
  • Cloudflare's Trace: You can visit https://yoursite.com/cdn-cgi/trace on a Cloudflare-protected site to see some of the basic metadata they collect about your connection.

Practical: Using tls-client for Perfect Mimicry

The standard libraries in Python, Go, and Node.js are not designed for mimicry. They are designed for RFC compliance. To get JA4+ right, you need a specialized library like tls-client.

tls-client allows you to specify a browser profile. When you select the Chrome_124 profile, it doesn't just change the User-Agent. It:

  1. Mimics the exact TLS extension order.
  2. Includes the correct GREASE values.
  3. Sets the H2 SETTINGS and WINDOW_UPDATE values to match Chrome.
  4. Uses the correct ALPN and cipher suites.
import tls_client

session = tls_client.Session(
    client_identifier="chrome_124",
    random_tls_extension_order=True
)

res = session.get(
    "https://example.com",
    headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
        "sec-ch-ua": '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
        # ... other headers
    }
)

By using a profile, you ensure that Part A, B, and C of your JA4 fingerprint are consistent with each other and with the browser you are claiming to be.

The Residential Proxy Layer

You can have a mathematically perfect TLS and HTTP fingerprint, but if you route that request through an AWS or Google Cloud IP, you will fail. Anti-bot systems in 2026 prioritize the ASN (Autonomous System Number) of the IP address.

Datacenter IPs are easily identified and carry a high "risk score." Residential proxies, which use IPs assigned to home internet users, are the only way to provide a clean IP signal that matches your "clean" browser fingerprint.

A perfect JA4 fingerprint + a premium residential proxy = a request that is indistinguishable from a real human user.

Conclusion

JA4+ is not just a trend; it's the new reality of web security. As we move further into 2026, the gap between simple scraping scripts and professional-grade extraction tools will only widen. Understanding the nuances of Part A/B/C, JA4H, and H2 settings is no longer optional—it is the baseline for any successful operation.

Ready to try the fastest residential proxies?

Join developers and businesses who trust ProxyLabs for mission-critical proxy infrastructure.

~200ms responseBest anti-bot bypass£2.50/GB
Start Building NowNo subscription required
tls fingerprintingJA3JA4anti-bot bypasscloudflareweb scrapingtls-clienthttp2
JL
James Liu
Lead Engineer @ ProxyLabs

Building proxy infrastructure since 2019. Previously failed at many things, now failing slightly less.

Found this helpful? Share it with others.

Share