Inferensys

Glossary

HTTP/2 Fingerprint

A method of identifying clients by analyzing the unique combination of SETTINGS frame values, pseudo-header order, and stream prioritization logic exchanged during an HTTP/2 connection handshake.
Stylish WeWork-like workspace with hot desks and document wall, professional searching through enterprise knowledge base on a mounted ultrawide display, warm industrial pendants overhead.
PASSIVE CLIENT IDENTIFICATION

What is HTTP/2 Fingerprint?

A method of identifying clients by analyzing the unique combination of SETTINGS frame values, pseudo-header order, and stream prioritization logic exchanged during an HTTP/2 connection handshake.

An HTTP/2 Fingerprint is a passive identification technique that profiles a client by inspecting the specific parameters and frame sequences it transmits during the initial HTTP/2 connection preface and SETTINGS frame exchange. Unlike HTTP/1.1, where the User-Agent string is easily spoofed, HTTP/2 requires clients to declare capabilities like SETTINGS_MAX_CONCURRENT_STREAMS, SETTINGS_INITIAL_WINDOW_SIZE, and SETTINGS_HEADER_TABLE_SIZE. The exact combination of these values, along with the order of pseudo-headers (:method, :path, :authority) and stream prioritization weights, creates a highly stable identifier that distinguishes a headless Chrome instance from a native browser or a Python httpx client from a legitimate crawler.

This technique is critical for AI crawler identification because autonomous agents and scraping libraries often use default HTTP/2 stacks that deviate from standard browser implementations. For instance, the Go HTTP client used by many scrapers sends a distinct SETTINGS frame order and lacks the WINDOW_UPDATE frame timing characteristic of Chromium-based browsers. Security architects integrate HTTP/2 fingerprinting into edge bot management platforms to passively reject traffic from unverified AI training bots, even when they present convincing User-Agent strings and residential IP addresses, providing a defense layer that operates below the JavaScript execution environment.

PROTOCOL-LEVEL IDENTIFICATION

Key Characteristics of HTTP/2 Fingerprints

HTTP/2 fingerprinting analyzes the unique, low-level parameters exchanged during the initial connection preface to identify specific client implementations, even when high-level identifiers like the User-Agent string are spoofed.

01

SETTINGS Frame Analysis

The SETTINGS frame is the cornerstone of HTTP/2 fingerprinting. During the connection preface, the client sends a SETTINGS frame containing a list of key-value pairs that configure the connection. The specific combination of parameters—such as SETTINGS_MAX_CONCURRENT_STREAMS, SETTINGS_INITIAL_WINDOW_SIZE, and SETTINGS_HEADER_TABLE_SIZE—varies significantly between browser engines, language libraries, and crawler implementations. For example, Chrome consistently advertises a maximum concurrent streams value of 1000, while Python's httpx library defaults to 100. These values are not arbitrary; they reflect the internal buffer allocations and concurrency models of each client.

02

Pseudo-Header Order

HTTP/2 mandates the use of pseudo-headers (:method, :path, :scheme, :authority) that precede regular headers in a request. While the specification requires pseudo-headers to appear before ordinary headers, it does not enforce a strict order among the pseudo-headers themselves. Different implementations serialize them in distinct sequences. For instance, Go's http2 library consistently sends :method, :scheme, :path, :authority, whereas Firefox uses :method, :path, :authority, :scheme. This ordering is a deeply embedded artifact of each client's HTTP/2 frame serializer and is extremely difficult to modify without patching the networking stack.

03

Stream Prioritization Logic

HTTP/2 introduces a stream prioritization mechanism using a dependency tree and weight system. Clients signal how the server should allocate bandwidth among concurrent streams by sending PRIORITY frames that define parent-child relationships and integer weights (1-256). The structure of this tree is a powerful fingerprinting vector. Chromium-based browsers build a complex, deeply nested prioritization tree to optimize rendering-critical resources, while simpler HTTP clients like curl or Python's requests often send a flat tree or omit PRIORITY frames entirely. The absence of prioritization is itself a strong signal of an automated agent.

04

HPACK Compression Behavior

HTTP/2 uses HPACK, a specialized compression algorithm for header fields, which relies on a shared dynamic table between client and server. The way a client populates and references this table reveals its implementation. Key fingerprinting signals include the dynamic table size advertised in SETTINGS, the choice of which headers are indexed versus transmitted literally, and the use of Huffman encoding for string literals. Browsers aggressively index common headers like :authority and content-type to maximize compression efficiency, while many lightweight crawler libraries perform minimal indexing, resulting in larger, less optimized header blocks that stand out under inspection.

05

WINDOW_UPDATE Strategy

Flow control in HTTP/2 is managed through WINDOW_UPDATE frames that govern how much data a receiver is willing to buffer. The timing and size of these updates expose the client's internal buffer management strategy. Browsers typically maintain large connection-level and stream-level windows, sending WINDOW_UPDATE frames proactively to avoid blocking. In contrast, many automated scrapers and bots use minimal window sizes or delay sending updates, creating a distinctive, constrained traffic pattern. This behavior is a direct reflection of the client's memory allocation strategy and is invisible to tools that only inspect static handshake parameters.

06

Frame Size and Multiplexing Patterns

The maximum frame size a client is willing to receive, declared in the SETTINGS_MAX_FRAME_SIZE parameter, and the actual sizes of frames it transmits are revealing. Browsers typically use the default maximum of 16,384 bytes for outgoing data frames, while some bots use smaller frames to reduce memory overhead. Additionally, the multiplexing behavior—how many streams a client opens concurrently and how it interleaves their frames—provides a behavioral fingerprint. Browsers open multiple streams for parallel resource loading and interleave frames aggressively. Automated crawlers often serialize requests, opening one stream at a time, which produces a distinctly non-browser-like multiplexing signature.

HTTP/2 FINGERPRINTING

Frequently Asked Questions

Technical answers to common questions about identifying clients through HTTP/2 connection parameters and handshake analysis.

An HTTP/2 fingerprint is a unique identifier derived from the specific combination of SETTINGS frame parameters, pseudo-header order, and stream prioritization logic that a client transmits during the initial connection preface. Unlike HTTP/1.1, where the User-Agent string is the primary identifier, HTTP/2 requires clients to exchange a series of predefined frames before any data flows. The SETTINGS frame contains key-value pairs like SETTINGS_MAX_CONCURRENT_STREAMS, SETTINGS_INITIAL_WINDOW_SIZE, and SETTINGS_HEADER_TABLE_SIZE. Each browser, library, or crawler implementation sets these values differently. For example, Chrome consistently sends SETTINGS_MAX_CONCURRENT_STREAMS as 1000, while Firefox uses 125. Python's httpx library sends SETTINGS_ENABLE_PUSH as 0 by default. By hashing the ordered sequence of these parameters along with the pseudo-header order (:method, :path, :authority, :scheme), a server can generate a stable fingerprint that persists even when the User-Agent string is spoofed. This technique is particularly effective against AI crawlers and headless browsers that use standard HTTP/2 libraries with predictable default configurations.

Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.