Agent context packet

Structured metadata, source alternates, graph links, headings, series position, and diagram inventory for crawlers and agent readers.

Table of contents

  1. JA4 / JA4T Fingerprint Quick Reference
  2. The Detection Hierarchy
  3. Layer 0: TCP/IP Fingerprinting
  4. The proxy problem
  5. Layer 1: TLS ClientHello
  6. JA3: the original, now largely obsolete
  7. JA4: the current standard
  8. The JA4+ family
  9. Browser TLS characteristics
  10. Layer 2: HTTP/2 SETTINGS
  11. Akamai fingerprint format
  12. Pseudo-header order: the silent identifier
  13. Layer 3: HTTP Headers
  14. Chrome 136 header sequence
  15. Firefox 144 header sequence
  16. Safari 260 header sequence
  17. Cross-header consistency
  18. GREASE in Sec-Ch-Ua
  19. The Players
  20. Cloudflare Bot Management
  21. Akamai Bot Manager
  22. DataDome
  23. What Changed in 2025-2026
  24. What Actually Matters vs. What’s Theater
  25. What matters
  26. What’s theater (for non-JS requests)
  27. Sources

Series context

How Domain Infrastructure Works

From DNS root servers through WHOIS/RDAP to TLS fingerprinting and bot detection — the full stack.

Audience: Developers building DNS tools, domain scanners, or anti-detection systems

  1. DNS Resolution: The Full Picture
  2. WHOIS Is Dead, Long Live RDAP
  3. How Websites Detect Bots in 2026 — JA4 & HTTP/2 Fingerprinting
  4. Domain Registration: From ICANN to Your Browser

Entry facts

Kind
article
Maturity
evergreen
Confidence
high
Origin
ai-drafted (AI-drafted, human-reviewed)
Author
Agent
Directed by
krow
Published
Modified
Words
3,481 (16 min read)
Series
domain-infrastructure #3
Tags
security, networking, fingerprinting, anti-detection, ja4, tls
Full corpus
/llms-full.txt
Readable corpus
/source/full-corpus/

Graph links

Related akamai-bot-manager-2026ja4-plus-fingerprint-suiteja4t-tcp-fingerprintingja4-fingerprint-t13d1516h2dns-resolution-full-picturetls-fingerprinting-curl-cffi

Tagssecurity, networking, fingerprinting, anti-detection, ja4, tls

How Websites Detect Bots in 2026 — JA4 & HTTP/2 Fingerprinting

How modern bot detection works: TLS/JA4 and HTTP/2 fingerprinting, header order, and behavioral signals across Cloudflare, Akamai, and DataDome.

/ directed by / / 16 min read
On this page

t13d1516h2 is the JA4 prefix for a TLS 1.3 ClientHello with SNI, 15 cipher suites after deduplication/GREASE removal, 16 extensions after deduplication/GREASE removal, and HTTP/2 ALPN. If you are seeing that string in logs, you are looking at the first, human-readable part of a JA4 TLS fingerprint; the later hash parts identify cipher-suite and extension details.

JA4 / JA4T Fingerprint Quick Reference

If you landed here searching for a specific fingerprint string, here’s the lookup table. The shorter JA4 t13d1516h2 snippet explains only that prefix; full breakdown in § JA4: the current standard below.

FingerprintDecodes toWhat it identifies
t13d1516h2t13 = TLS 1.3, d = SNI present, 15 ciphers, 16 extensions, h2 = HTTP/2 ALPNThe JA4 part A prefix shared by all modern Chrome / Edge / Brave on TLS 1.3 (the PSK-resumption variant is t13d1517h2). Firefox is t13d1715h2, Safari t13d2014h2.
t13d1516h2_8daaf6152771_02713d6af862Chrome 120 – 131 (full JA4)Stable across version bumps because part B/C are SHA256 of sorted ciphers + extensions.
t13d1516h2_8daaf6152771_d8a2da3f94cdChrome 133 – 136+Part C changed only because Chrome updated its signature_algorithms list between 131 and 133.
t13d1516h2_8daaf6152Truncated formThe 12-character _<hashB> short form some logs and threat-intel feeds emit. Same browser family as the full hash.

Tooling: curl_cffi reproduces these from Python; native curl and Go’s net/http cannot.

If you’re looking for the inverse — given a fingerprint, what’s the browser? — search ja4db.com or the FoxIO-LLC/ja4 repo. This article explains the why behind the format so the table makes sense.

The Detection Hierarchy

Bot detection is a layered system. Each layer fires at a different point in the connection lifecycle, and each one can reject you before the next layer even runs. Here’s the order, from earliest to latest:

  1. TCP/IP fingerprint — before encryption, before HTTP, before anything
  2. TLS ClientHello — during the handshake, before any application data
  3. HTTP/2 SETTINGS — the first application frame after TLS completes
  4. HTTP header order and values — the actual request
  5. Client Hints coherence — cross-header consistency checks
  6. IP reputation / ASN classification — datacenter IP = suspicion
  7. Behavioral signals — timing, navigation patterns, mouse movement

The critical insight: layers 1-4 are checked before a single byte of your “page content” loads. No JavaScript runs. No CAPTCHA renders. The server already knows if your connection looks like a browser or a script.

Modern anti-bot systems look for cross-layer consistency — what they call “stack drift.” A perfect TLS fingerprint paired with wrong HTTP/2 settings is more suspicious than getting both slightly wrong. Every layer must tell the same story.

If you want the broader network path those layers sit on — resolver, recursive DNS, authoritative DNS, TLS, then HTTP — DNS Resolution: The Full Picture is the right companion piece.

Layer 0: TCP/IP Fingerprinting

The TCP SYN packet — the very first packet of any connection — reveals the operating system. This happens before encryption, before TLS, before HTTP. The server (or its CDN) sees raw TCP parameters that differ by OS:

ParameterLinuxWindowsmacOS
Initial TTL6412864
TCP Window Size29,200 (kernel 3.x) / 64,240 (5.x+)65,53565,535
Window Scale78varies
TCP Options OrderMSS, SACK_PERM, TIMESTAMP, NOP, WSCALEMSS, NOP, WSCALE, NOP, NOP, SACK_PERM (no TIMESTAMP)MSS, NOP, WSCALE, NOP, NOP, TIMESTAMP, SACK_PERM

Windows is the outlier: TTL of 128, no TIMESTAMP option. Linux and macOS share TTL 64 but differ in TCP options order. Tools like p0f and Zardaxt (used by DataDome in production) classify OS from these values.

The JA4T fingerprint formalizes this: Window_Size, Options, MSS, TTL. It’s compact enough to index and fast enough to check on every connection. See JA4T TCP fingerprinting for how the SYN window, MSS, and option order combine into the hash.

The proxy problem

When traffic routes through a proxy (SOCKS5, CONNECT), the target server sees the proxy’s TCP stack, not yours. If the proxy runs Linux (TTL=64, Linux TCP options) but your User-Agent claims Windows (TTL=128, Windows TCP options), that’s a detectable mismatch.

In practice, most proxy servers run Linux. This means:

  • macOS User-Agents: Safe. macOS and Linux both use TTL=64, so the TCP layer is consistent.
  • Windows User-Agents: Risky. TTL=64 from the Linux proxy contradicts the expected TTL=128 from a Windows machine.

This is the kind of cross-layer inconsistency that modern systems catch — the TCP layer and the HTTP layer are telling different stories about the operating system.

Layer 1: TLS ClientHello

The TLS handshake happens before any HTTP data crosses the wire. The ClientHello message contains a rich set of signals:

  • Cipher suites: count, order, values (including GREASE tokens)
  • TLS extensions: count, order, values (including BoringSSL-specific ones)
  • Supported groups (elliptic curves)
  • Signature algorithms
  • ALPN values (h2, http/1.1)
  • Key share groups

Each browser has a distinct combination. Chrome uses BoringSSL, Firefox uses NSS, Safari uses Apple’s SecureTransport. The crypto libraries produce fundamentally different ClientHello messages — different cipher suites, different extension sets, different ordering.

JA3: the original, now largely obsolete

JA3 hashes TLS version + cipher suites + extensions + elliptic curves + EC point formats into an MD5 fingerprint. It worked well until Chrome 110 (January 2023) introduced TLS extension order randomization — a deliberate anti-fingerprinting measure. Now every Chrome connection produces a different JA3 hash:

Impersonation TargetJA3 Hash
Chrome 1209cc9e346...
Chrome 124351d0eae...
Chrome 131cdbf6205...
Chrome 133a6d135b0...
Chrome 1362d04cd75...

Different hash every time, same browser. JA3 is still useful for detecting non-browser clients (Python requests, Go’s net/http, raw curl) which don’t randomize — but it’s useless for distinguishing Chrome versions.

JA4: the current standard

JA4, universally adopted by Cloudflare, AWS WAF, VirusTotal, and Akamai as of 2026, fixes this with a three-part fingerprint: a_b_c. (How Cloudflare uses JA3 and JA4 breaks down their specific scoring.)

  • Part A (human-readable): protocol type, TLS version, SNI presence, cipher count, extension count, first ALPN
  • Part B: SHA256 of sorted cipher suites — immune to randomization
  • Part C: SHA256 of sorted extensions + signature algorithms

Sorting before hashing is the key innovation. Chrome can randomize extension order all it wants — the sorted hash is stable.

Empirical captures confirm this. All Chrome 120-131 targets produce the same JA4 parts A and B, with part C changing only when Chrome updated its signature algorithms between versions 131 and 133:

Chrome Version RangeJA4
120 - 131t13d1516h2_8daaf6152771_02713d6af862
133 - 136+t13d1516h2_8daaf6152771_d8a2da3f94cd

The t13d1516h2 prefix decodes to: TLS 1.3, 15 cipher suites (after deduplication/GREASE removal), 16 extensions, HTTP/2 ALPN. Cloudflare sees 15 million unique JA4 fingerprints daily across 500 million+ user agents. A Python script using the requests library has a JA4 that matches exactly zero of those 15 million real browser fingerprints.

The JA4+ family

JA4 spawned a family of fingerprints covering the full stack. The dedicated JA4+ fingerprint suite page expands this list into packet-layer placement, use cases, and licensing boundaries:

  • JA4S: Server Hello fingerprint
  • JA4H: HTTP client fingerprint (header names, values, cookies)
  • JA4X: X.509 certificate fingerprint
  • JA4T: TCP fingerprint (Layer 0 above)
  • JA4SSH: SSH fingerprint

These are composable. A detection system can check JA4 (TLS) + JA4T (TCP) + JA4H (HTTP) for cross-layer consistency in a single lookup.

Browser TLS characteristics

Each browser family has a distinct cipher suite profile:

BrowserCipher SuitesExtensions
Chrome1618 (15 + 3 GREASE)
Firefox1716-17
Safari2014

Safari has the most cipher suites but fewest extensions. Firefox sits in the middle. These counts alone narrow the field before you even look at values. For worked examples see Safari’s JA4 fingerprint t13d2014h2 and the catalog of common JA4 fingerprints decoded.

Layer 2: HTTP/2 SETTINGS

Immediately after TLS, the HTTP/2 connection opens with a SETTINGS frame. Each browser sends different parameters — and this alone is enough to distinguish Chrome, Firefox, and Safari.

Akamai fingerprint format

The industry-standard format is: SETTINGS|WINDOW_UPDATE|PRIORITY|PSEUDO_HEADER_ORDER

Empirical captures from each browser:

BrowserAkamai HTTP/2 Fingerprint
Chrome1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p
Firefox1:65536;2:0;4:131072;5:16384|12517377|0|m,p,a,s
Safari2:0;3:100;4:2097152;9:1|10420225|0|m,s,p,a

These are completely distinct. Chrome uses INITIAL_WINDOW_SIZE of 6,291,456. Firefox uses 131,072 — 48x smaller. Safari uses entirely different SETTINGS IDs (3=MAX_CONCURRENT_STREAMS, 9=SETTINGS_ENABLE_CONNECT_PROTOCOL) that Chrome doesn’t even send.

The WINDOW_UPDATE values differ too: Chrome sends 15,663,105; Firefox 12,517,377; Safari 10,420,225.

Pseudo-header order: the silent identifier

HTTP/2 requires four pseudo-headers (:method, :authority, :scheme, :path) before any regular headers. The order is technically arbitrary, but each browser has a fixed convention:

BrowserPseudo-Header Order
Chrome:method, :authority, :scheme, :path (masp)
Firefox:method, :path, :authority, :scheme (mpas)
Safari:method, :scheme, :path, :authority (mspa)
curl (default):method, :path, :scheme, :authority (mpsa)

Note that default curl matches no browser at all. This single signal — four headers in the wrong order — is enough to flag a connection as automated. An HTTP client that gets TLS right but sends pseudo-headers in curl’s default order is trivially detected.

This fingerprint is stable across versions. All Chrome targets from version 120 through 142 produce the identical HTTP/2 SETTINGS and pseudo-header order. The HTTP/2 implementation changes far less frequently than TLS parameters.

Layer 3: HTTP Headers

Header order, presence, and values are all signals. Each browser sends headers in a fixed, characteristic sequence, and anti-bot systems compare the observed order against known-good patterns.

Chrome 136 header sequence

:method, :authority, :scheme, :path
sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform
upgrade-insecure-requests, user-agent, accept
sec-fetch-site, sec-fetch-mode, sec-fetch-user, sec-fetch-dest
accept-encoding, accept-language, priority

Firefox 144 header sequence

:method, :path, :authority, :scheme
user-agent
accept, accept-language, accept-encoding
upgrade-insecure-requests
sec-fetch-dest, sec-fetch-mode, sec-fetch-site, sec-fetch-user
priority, te: trailers

Safari 260 header sequence

:method, :scheme, :authority, :path
sec-fetch-dest
user-agent, accept
sec-fetch-site, sec-fetch-mode
accept-language, priority, accept-encoding

The differences are striking:

  • Client Hints (sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform): Chrome-only. Firefox and Safari never send them. If your request claims to be Firefox but includes sec-ch-ua headers, it’s instantly flagged.
  • te: trailers: Firefox-only. No other browser sends it.
  • sec-fetch-dest position: Chrome sends it after sec-fetch-mode. Safari sends it first among regular headers. Firefox sends it first among the sec-fetch group.
  • accept-encoding position: Chrome sends it near the end. Safari sends it last. Firefox sends it after accept-language.
  • user-agent position: Chrome sends it in the middle (after upgrade-insecure-requests). Firefox sends it first among regular headers. Safari sends it after sec-fetch-dest.

Cross-header consistency

Headers must agree with each other:

Signal AMust MatchSignal B
sec-ch-ua-platformUser-Agent OS string
sec-ch-ua browser versionTLS JA4 fingerprint
accept-languageProxy IP geolocation
HTTP/2 pseudo-header orderTLS fingerprint (browser identity)
sec-fetch-* valuesRequest context (navigation vs. API call)

A request with sec-ch-ua-platform: "Windows" and User-Agent: ...Macintosh; Intel Mac OS X... is an instant fail — the kind of cross-header mismatch that DataDome and equivalents call out explicitly in their bypass-prevention guidance.

GREASE in Sec-Ch-Ua

Chrome rotates the “Not A Brand” GREASE string per version:

  • Chrome 136: "Not.A/Brand";v="99"
  • Chrome 138: "Not)A;Brand";v="8"

The GREASE brand in sec-ch-ua must match the Chrome version claimed by the TLS fingerprint. A stale GREASE string is a version mismatch signal.

The Players

Cloudflare Bot Management

Cloudflare’s bot-detection ML analyzes over 46 million HTTP requests per second in real time — that’s the model’s input rate, not Cloudflare’s total network traffic.

The detection stack is multi-engine:

  • ML model (v8) — three feature categories (global inter-request aggregates, high-cardinality per-IP patterns, single-request signals). In one published case study against a distributed residential-proxy attack on a voucher endpoint, v8 classified 95% of requests correctly; the same blog notes a 20% lift on cloud-provider bots and up to 70% on zones marked “under attack.”
  • Heuristics enginearound 50 hand-written rules on HTTP/2 fingerprints and ClientHello extensions, written by Cloudflare’s bot-detection analysts since mid-2025.
  • JS Detection (JSD) — identifies headless browsers via navigator.webdriver, missing APIs, and DOM-level signals.
  • Per-customer ML (2025) — anomaly models trained per zone, so what looks normal for a SaaS dashboard is anomalous for an e-commerce storefront. Customer data is not shared across zones.

The JA4-specific signal is concrete: Cloudflare’s JA4 signals blog reports analyzing “over 15 million unique JA4 fingerprints generated from more than 500 million user agents and billions of IP addresses” daily, and correlating JA4 against the claimed User-Agent. A mismatch between observed TLS behavior and the browser the request claims to be is a primary signal.

Cloudflare also detects Chrome DevTools Protocol (CDP) artifacts that persist even when common patches (removing navigator.webdriver, etc.) are applied. CDP coverage among browser-based bots is broadly cited as near-universal in vendor commentary, though Cloudflare’s exact deployment numbers aren’t public.

Turnstile (Cloudflare’s CAPTCHA replacement): independent benchmarks have measured detection rates dramatically lower than reCAPTCHA — Roundtable Research’s bot-benchmarking reports figures on the order of Turnstile ~33% / reCAPTCHA ~69%. The methodology gap is by design — Turnstile validates the browser environment but explicitly skips behavioral analysis. For HTTP-level automation that never executes JavaScript, Turnstile is irrelevant either way: it needs a browser context to render.

Akamai Bot Manager

Akamai Bot Manager detection in 2026 is now split out as its own page. The short version: Akamai combines validated/custom bot categories, transparent request-anomaly detection, active browser checks, Premier behavioral detection, Bot Score thresholds, and protocol context such as JA4 or HTTP/2 fingerprints. The SETTINGS|WINDOW_UPDATE|PRIORITY|PSEUDO_HEADER_ORDER HTTP/2 format described above originated from Akamai’s Black Hat EU 2017 research, but Bot Manager decisions are broader than that one fingerprint.

Akamai’s public rollout advice also matters: start in monitor mode, learn the traffic mix, then apply response tiers such as allow, challenge, tarpit, slow, or deny. That keeps the product from becoming a brittle “block the hash” rule when the request is really a known crawler, a mobile app, a partner integration, or a human user behind a strange network path.

DataDome

DataDome reports processing over 5 trillion signals per day (up from 3 trillion) at sub-2ms response time, and runs 85,000+ customer- and use-case-specific models plus a heuristic layer:

Server-side signals (heavier weight in their scoring):

  • Request header analysis (order matters)
  • HTTP version detection
  • TLS/JA3/JA4 fingerprinting
  • IP reputation scoring
  • TCP/IP OS fingerprinting — one of the few vendors openly using Layer 0; their write-ups cite the Zardaxt approach in particular

Client-side signals (behavioral):

  • Mouse movement, scroll velocity, typing cadence, click coordinates
  • GPU rendering capabilities, font availability, JS engine specifics
  • LLM crawler traffic detection (added 2025)

In practice, the server-side stack carries more weight in DataDome’s scoring than the client-side JS fingerprint surface — partly because JS fingerprinting is noisier (browser-version drift, extension interference) and partly because evasive bots have spent years optimizing precisely that surface. For requests that never execute JavaScript, the TLS + HTTP/2 + header layers are effectively the entire detection budget.

What Changed in 2025-2026

The bot detection landscape shifted significantly:

JA4 replaced JA3 as the industry standard. Chrome’s TLS extension randomization (since Chrome 110, January 2023) made JA3 unreliable for browser identification. JA4’s sorted-before-hashing approach solved this. By 2026, Cloudflare, AWS WAF, VirusTotal, and Akamai all use JA4 as a primary signal.

Detection moved upstream. The trend is toward catching bots earlier in the connection lifecycle. TLS handshake checks happen before the page loads, before JavaScript runs, before any CAPTCHA renders. If your ClientHello looks wrong, the connection may be terminated or routed to a honeypot before HTTP even begins.

Per-customer ML models arrived. Cloudflare’s per-customer models (2025) train on each site’s specific traffic patterns. A request that looks normal globally can be anomalous for a specific site. This makes generic evasion harder — you need to look normal for the specific site you’re accessing, not just for the internet in general.

Residential proxy detection improved. Cloudflare’s v8 ML model claims per-request detection of residential proxy abuse without IP blocking. The signals include request timing, header patterns, and behavioral fingerprints that distinguish real residential users from proxy traffic, even when the IP itself is classified as residential.

CDP detection became standard. Chrome DevTools Protocol detection is now a primary signal. CDP leaves artifacts in the browser environment that persist even when common patches (like removing navigator.webdriver) are applied. Anti-bot vendors broadly cite CDP as near-universal among headless-browser-based bot stacks; exact percentages are vendor-internal.

Fingerprint inconsistency detection formalized. FP-Inconsistent (IMC 2025) introduced data-driven rules for detecting both spatial inconsistencies (cross-attribute contradictions in a single request) and temporal inconsistencies (an attribute changing across requests from the same device). Against bot traffic from 20 commercial bot services, the approach reduced evasion success by 44.95–48.11% while keeping a 96.84% true-negative rate on real users.

What Actually Matters vs. What’s Theater

For HTTP-level requests that don’t execute JavaScript (API calls, data fetching, scraping), the detection stack collapses to a smaller set of signals that actually matter:

What matters

  1. TLS fingerprint (JA4): The single most important signal. A Python requests library has a JA4 that matches zero real browsers. Using a TLS library that replays a real browser’s ClientHello is table stakes — see TLS Fingerprinting with curl_cffi for how this works in practice.

  2. HTTP/2 SETTINGS + pseudo-header order: The second gate. Default curl sends pseudo-headers in mpsa order, matching no browser. Chrome uses masp, Firefox mpas, Safari mspa. Wrong SETTINGS values or wrong pseudo-header order flags the connection before the first header is read.

  3. Header order and presence: Chrome, Firefox, and Safari each send headers in a fixed, characteristic sequence. Missing sec-fetch-* headers when claiming to be Chrome is an automation signal. Including sec-ch-ua when claiming to be Firefox is equally bad.

  4. Cross-layer consistency: Every signal must agree. TLS says Chrome 136, headers must say Chrome 136, sec-ch-ua-platform must match the User-Agent OS, and accept-language should be plausible for the IP’s geolocation.

  5. IP reputation: Datacenter ASNs are flagged by default. Residential IPs get more trust but are increasingly fingerprinted themselves. When building high-throughput systems that hit these detection layers, adaptive rate limiting becomes essential to avoid triggering behavioral signals.

What’s theater (for non-JS requests)

  • JavaScript fingerprinting: Irrelevant if you never execute JS. Canvas fingerprinting, WebGL rendering, navigator property checks — none of these fire for a simple HTTP request.
  • Behavioral signals: Mouse movement, scroll patterns, typing cadence — these require a browser context. For API-style requests, behavioral analysis is limited to request timing and navigation patterns.
  • CAPTCHAs and Turnstile: These require a browser to render. They’re a gate for browser traffic, not for HTTP clients.

The practical implication: for simple HTTP requests, the TLS + HTTP/2 + header stack is the gate you have to clear. Get those three layers right and consistent, and you clear the fingerprint check — though IP reputation, ASN, and per-customer ML still apply. Get any one of them wrong, and everything downstream is irrelevant — you’re already flagged before your request body is read.

Sources

Diagram

Drag to pan · scroll or pinch to zoom · Esc to close