Skip to content
All fingerprint checksTLS & the network layer

the TLS fingerprint is the same on two separate connections

Check id ja4-stable-across-connections

What an ordinary browser yields

Two independent handshakes from one browser produce byte-identical JA4 fingerprints, because the ClientHello is built from compiled-in preferences rather than generated per connection.

What a detector infers

Everything else on this page reads the browser through JavaScript. This reads it through its own TLS handshake — the one surface a page genuinely cannot see. JA3 and JA4 are computed from the raw ClientHello: the cipher list, the ORDER of the extensions, the curves, ALPN, and where GREASE was injected. None of it is reachable from script, and not for privacy reasons — it is emitted by the TLS stack before a line of page code exists. Only a server that terminated the handshake knows it, which is why this check is the only one here that leaves the machine. The audit fetches two probes on one host across two ports. Different ports are different origins, so the browser cannot satisfy the second fetch by reusing the first connection, and its TLS session cache is keyed per port — each probe forces a full, fresh ClientHello. The probe server also refuses to issue session tickets, and that detail is load-bearing: a resumed handshake carries pre_shared_key extensions the first one did not, which moves the extension count and the JA4 hash, and an entirely honest browser would look like it had randomised its own fingerprint. Now the assertion, and what it deliberately is not. It does not ask whether your JA4 is Chrome's. That needs a fingerprint corpus, and corpora rot — this audit already shipped one, a table of V8 heap sizes, which went stale and started calling a stock Chrome implausible; a JA4 database rots faster still, because Chrome's ClientHello moves between releases. Instead it asks the one question that needs no reference at all: one TLS stack, asked twice, must answer twice the same. A browser's ClientHello is assembled from preferences compiled into the binary, so it cannot vary between two connections seconds apart. Tooling that randomises the ClientHello to defeat fingerprinting is caught by the randomisation itself — the variation is the signal.

How to resolve it

A randomised ClientHello is more legible than a fixed one, not less: no real TLS stack rewrites its own cipher and extension list between two connections seconds apart, so the variation is itself the finding. If your TLS profile must differ from the browser's own, it has to be a consistent profile — impersonate one stack completely rather than sampling a new one per connection.

What is a JA3 / JA4 TLS fingerprint?

Other checks in TLS & the network layer

Who builds this test

Clearcote is a browser built for fingerprint coherence

It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.

This audit takes no position on how Clearcote scores on TLS & the network layer checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.

See the other checks in TLS & the network layer — the family ja4-stable-across-connections belongs to.