# Why Chrome's JA4 differs between versions

> Chrome 152 read t13d1517h2 and 153 read t13d1518h2: one TLS extension apart. Compare a JA4 only against a Chrome of the same major version.

Source: https://mosaicbrowser.com/blog/ja4-moves-with-the-chrome-major

## JA4 moves with the Chrome major, and that is not a tell

Chrome 152 read t13d1517h2 and 153 read t13d1518h2: one TLS extension apart. Compare a JA4 only against a Chrome of the same major version.

![17 / 18: Chrome 152 and 153, one extension apart, beside a screenshot: the Mosaic sidebar with profiles running, each with its own window](https://mosaicbrowser.com/covers/ja4-moves-with-the-chrome-major.webp)

Chrome's JA4 changes between versions because Chrome's own TLS stack changes between versions. When our engine was on 153, Google Chrome 152 on the same machine read `t13d1517h2`, while Google's Chrome for Testing 153 read `t13d1518h2`: seventeen TLS extensions against eighteen. Neither was wrong. A JA4 compared against a different Chrome major reports that difference as if it were a finding, and it is not one.

## What the parts of a JA4 say

A JA4 has three parts separated by underscores. Ours, measured on one profile against Google's Chrome for Testing 153.0.8010.36, was:

```
t13d1518h2_8daaf6152771_4980c97edce0

```

The first part is readable. `t` is TCP, `13` is TLS 1.3, `d` means the browser sent a domain name in SNI, `15` is the number of cipher suites, `18` the number of extensions, and `h2` the first protocol it offered over ALPN. The second part is a truncated hash of the cipher suites, sorted. The third is a hash of the extensions, sorted, together with the signature algorithms.

Sorting is what makes JA4 hold still. Chrome shuffles its extension order on every connection, and JA3, which hashes the order as sent, changes with every shuffle. JA4 sorts first and leaves out the GREASE values Chrome scatters in, so the same binary gives the same JA4 every time. Our [post on JA3](https://mosaicbrowser.com/blog/why-chromes-ja3-changes) has the measurements of that.

Mosaic is a desktop app

Email yourself the link and open it on your computer.

[How it works: Machines that exist](https://mosaicbrowser.com/features/real-fingerprints)

## Why Chrome's JA4 is different between versions

A sorted list stays the same until the list itself changes, and from one major to the next Chrome changes it. Extensions are added as new TLS features ship, and old ones go. In our run, 153 sent one more extension than 152, so the extension count in the prefix went from 17 to 18. A sorted list with a different set of entries hashes differently too, so the third part moves with it.

That is the browser updating, nothing more. On the same Mac, a stock 153 build sent eighteen extensions and a stock 152 sent seventeen. Both are handshakes real Chrome users send, because people update at different speeds. A site comparing your JA4 against the population of its own visitors sees whichever one matches the version you claim.

## Other reasons one Chrome can show two JA4s

Version is the big one, but the prefix has other letters, and each of them follows the connection rather than the browser:

- Over QUIC, which Chrome uses for HTTP/3, the first letter is `q`, not `t`.
- A connection to a bare IP address sends no domain name, so `d` becomes `i`.
- The last two characters follow what the browser offered over ALPN on that connection.

So before reading two JA4s as two browsers, check they describe the same kind of connection. A TLS echo page reached over TCP and one reached over QUIC can show the same Chrome twice under two prefixes.

## Comparing across majors invents findings

This is why our own comparison tool refuses to run across versions. `check:stock` launches a profile and a stock Chrome side by side and diffs what each exposes. If the two binaries report different Chrome majors, it prints "The profile launched Chromium" with both numbers, says a diff across majors "reports every API added in between as a difference, and none of them would be a leak", compares nothing and exits.

The tempting fix for a red diff is to add the differences to an allow-list until it goes green. That would have made the tool a rubber stamp. Refusing is also the honest prompt to move our patches onto the newer Chrome.

The same discipline cut the other way once. For weeks `check:stock` compared against Chrome for Testing, Google's unbranded build, and passed. Measured against the Google Chrome people actually install, twenty API entries differed, because an unbranded build runs field trials that branded Chrome does not. The control has to be the browser people run, at the version you claim.

## What a JA4 should match

A profile that claims Chrome 153 should send Chrome 153's handshake. Ours did, byte for byte: 15 cipher suites, 18 extensions, ALPN `h2`, and both hashes equal to stock. Tesseract Chrome is Chromium built from stock source, so it inherits Chrome's TLS stack unchanged, and it has no switch to vary the handshake per profile. [Why there is no TLS fingerprint setting](https://mosaicbrowser.com/blog/no-tls-fingerprint-setting) gives the reasoning.

What would be a tell is a mismatch inside one browser: a User-Agent claiming one major over a handshake from another. A network-level detector reads the handshake before any JavaScript runs, so that contradiction is the first thing it sees. To compare your own, read the JA4 from a TLS echo service in the browser you are testing and in a real Chrome of the same version, and compare the two JA4 strings, not the JA3s. A web page alone cannot see the raw ClientHello; our [TLS fingerprint page](https://mosaicbrowser.com/tools/tls-fingerprint) shows what a page can read of your connection and explains the rest.

## Questions

### Why is Chrome's JA4 different between versions?

Each Chrome major can add, drop or change TLS extensions and cipher suites. JA4 counts and hashes both lists, so a change in Chrome's own TLS stack shows up as a different JA4 even though nothing about the browser is unusual.

### Can one Chrome version have more than one JA4?

Yes. A connection over QUIC starts with q where TCP starts with t, a connection to a bare IP address carries i where a domain name carries d, and the ALPN characters follow what the browser offered. Compare like with like.

### Does the extension shuffle change JA4?

No. JA4 sorts the cipher and extension lists before hashing and leaves out GREASE values, so Chrome's per-connection reordering does not move it. JA3 does change with the shuffle.

### How should I test an anti-detect browser's TLS fingerprint?

Against a real Chrome of the same major version, on the same machine, in the same minute. Our engine and Google's Chrome for Testing 153 produced the identical JA4, t13d1518h2_8daaf6152771_4980c97edce0.

## Related

[Why Chrome's JA3 hash changes on every connection](https://mosaicbrowser.com/blog/why-chromes-ja3-changes): Chrome's JA3 changes because Chrome shuffles its TLS extension order on every connection, and JA3 hashes that order. JA4 sorts first and holds still.

[Why our engine has no TLS fingerprint setting](https://mosaicbrowser.com/blog/no-tls-fingerprint-setting): You can't change Chrome's TLS fingerprint from a setting, and we chose not to patch it: our engine's JA4 matched Google's own build byte for byte.

[Introducing Mosaic, an anti-detect browser that lives on your machine](https://mosaicbrowser.com/blog/introducing-mosaic): Mosaic runs its own Chromium, draws each profile from a real machine and matches it to the proxy exit. Profiles stay on disk. One plan, no per-profile fees.











## Mosaic, on your own computer

The browser this blog is about: its own Chromium, fingerprints from real machines and a proxy exit per profile. Free holds 3 profiles. Pro is $49 a month for any number.

Mosaic is a desktop app

Email yourself the link and open it on your computer.
