Agent context packet

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

Table of contents

  1. The format
  2. SETTINGS
  3. WINDOW_UPDATE
  4. PRIORITY
  5. Pseudo-header order
  6. The real values
  7. Why it’s a strong signal
  8. What this means for impersonation
  9. HTTP/3 moves the surface
  10. Sources

Entry facts

Kind
article
Maturity
budding
Confidence
high
Origin
ai-drafted (AI-drafted, human-reviewed)
Author
Agent
Directed by
krow
Published
Modified
Words
1,055 (5 min read)
Tags
http2, fingerprinting, bot-detection, anti-detection, networking
Prerequisites
Full corpus
/llms-full.txt
Readable corpus
/source/full-corpus/

Graph links

Prerequisites bot-detection-2026

Related akamai-bot-manager-2026bot-detection-2026ja4-plus-fingerprint-suiteja4t-tcp-fingerprintingja4-vs-ja3tls-fingerprinting-curl-cffi

Tagshttp2, fingerprinting, bot-detection, anti-detection, networking

HTTP/2 Fingerprinting: The Akamai Format

How the Akamai HTTP/2 fingerprint works — SETTINGS, WINDOW_UPDATE, PRIORITY, and pseudo-header order: the layer after JA4 that default clients fail.

/ directed by / / 5 min read
On this page

A JA4 TLS fingerprint identifies the client from its ClientHello. But the handshake isn’t the last thing the server sees before your request — once TLS completes, the client opens an HTTP/2 connection, and the very first frames it sends are just as identifying. The Akamai HTTP/2 fingerprint captures that connection preface. A real Chrome and a requests-with-a-Chrome-User-Agent diverge here before a single header is read.

This sits one layer above JA4 in the bot-detection stack: JA4 is the TLS handshake; this is the HTTP/2 setup that immediately follows on the same connection. In product context, Akamai Bot Manager uses this kind of protocol evidence alongside transparent request checks, active browser checks, behavioral detection, reputation, and response strategy. For the full cross-layer map — JA4S, JA4H, JA4X, JA4L, JA4SSH, and JA4T — see the JA4+ fingerprint suite.

The format

Akamai’s Black Hat EU 2017 research defined a fingerprint from four client-controlled parts of the HTTP/2 connection preface, joined by |:

SETTINGS | WINDOW_UPDATE | PRIORITY | PSEUDO_HEADER_ORDER

A real Chrome 144 fingerprint:

1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p

Each field is a deliberate implementation choice the client makes the same way every time — which is exactly what makes the concatenation a stable identifier.

SETTINGS

The client’s opening SETTINGS frame, as id:value pairs in send order, semicolon-separated. The standard parameter IDs (RFC 9113 §6.5.2):

IDNameWhat it controls
1HEADER_TABLE_SIZEHPACK dynamic table size
2ENABLE_PUSHServer push allowed (browsers send 0)
3MAX_CONCURRENT_STREAMSParallel streams the peer may open
4INITIAL_WINDOW_SIZEPer-stream flow-control window
5MAX_FRAME_SIZELargest frame the client will accept
6MAX_HEADER_LIST_SIZELargest header block the client will accept

Newer clients also send extension IDs — 8 (ENABLE_CONNECT_PROTOCOL, RFC 8441) and 9 (NO_RFC7540_PRIORITIES, RFC 9218) — and Safari’s 9:1 is one of the clearest tells in its fingerprint.

The set of IDs sent, their values, and their order all vary by client. Chrome sends INITIAL_WINDOW_SIZE of 6,291,456 (6 MiB); Firefox sends 131,072 (128 KiB) — a 48× difference in one field.

WINDOW_UPDATE

A single integer: the increment in the client’s first connection-level WINDOW_UPDATE frame, or 0 if none was sent. Chrome sends 15663105, Firefox 12517377, Safari 10420225. These are fixed per client.

PRIORITY

Zero or more PRIORITY tuples, each StreamID:Exclusive:DependentStreamID:Weight, comma-separated — or 0 if the client sends none. Chrome sends none (0); Firefox historically builds a priority tree (e.g. 3:0:0:201), which is itself a strong Firefox signal. With RFC 9218 deprecating the RFC 7540 priority scheme, newer clients increasingly send none.

Pseudo-header order

The cheapest, highest-signal field. HTTP/2 carries the request line as four pseudo-headers — :method, :authority, :scheme, :path — and the order the client emits them is hardcoded per implementation, encoded as the first letters (m, a, s, p):

ClientPseudo-header orderCode
Chrome / Chromium:method, :authority, :scheme, :pathm,a,s,p
Firefox:method, :path, :authority, :schemem,p,a,s
Safari:method, :scheme, :path, :authoritym,s,p,a
curl (default):method, :path, :scheme, :authoritym,p,s,a

The last row is the point: a default HTTP client’s pseudo-header order matches no browser. This single field flags a connection as automated before the request headers are even parsed — and unlike a User-Agent string, you can’t fix it by setting a header.

The real values

Putting the fields together, here’s what each browser actually emits:

ClientAkamai 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

Three browsers, three distinct SETTINGS sets, three WINDOW_UPDATE values, three pseudo-header orders. Safari is the odd one out twice over: it omits HEADER_TABLE_SIZE, and it sends 9:1 to opt out of RFC 7540 priorities.

Why it’s a strong signal

It’s stable. A client’s HTTP/2 stack changes far less often than its TLS parameters. Chrome’s SETTINGS and pseudo-header order have held across many major versions, so a detection vendor can match against a fixed value without the per-version churn that plagued JA3.

It’s early and unspoofable-by-header. The fingerprint is set by the HTTP/2 library, not by request headers. You can put any User-Agent you like on the request; if your client library emits curl’s m,p,s,a pseudo-header order, you’ve already lost.

It composes with the other layers. Anti-bot systems check for cross-layer consistency. A request whose JA4 says Chrome but whose HTTP/2 fingerprint says Go net/http is more suspicious than one that gets both slightly wrong — the two layers disagree about what the client is. JA4 + HTTP/2 + header order have to tell the same story.

What this means for impersonation

This is why a browser User-Agent on requests or stock curl doesn’t work: those clients send their own HTTP/2 fingerprint, which no browser produces. A library like curl_cffi replays the target browser’s SETTINGS frame, WINDOW_UPDATE, and pseudo-header order alongside its TLS handshake — getting both the JA4 and the HTTP/2 layer right at once. The impersonation library comparison covers which libraries replay the HTTP/2 layer faithfully and which only handle TLS.

You can read your own client’s HTTP/2 fingerprint at services like tls.peet.ws — the same probe that surfaces your JA4 also reports the Akamai HTTP/2 hash, which is the cheapest way to confirm an impersonation library replayed this layer before you rely on it.

HTTP/3 moves the surface

HTTP/3 runs over QUIC, not TCP+TLS+HTTP/2, so the fingerprint surface shifts again: the SETTINGS-frame and pseudo-header signals largely carry over, but they now sit alongside QUIC transport parameters and the QUIC initial packet. The principle is unchanged — every protocol layer the client configures is a layer it can be identified by.

Sources

Diagram

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