# FingerprintJS: "Chromium-Based Browser Not Available"

> FingerprintJS read 'Chromium-Based Browser Not Available' for our engine. We blamed the version; the real variable was Google's branding.

Source: https://mosaicbrowser.com/blog/fingerprintjs-cannot-name-browser

## When the FingerprintJS demo can't name your browser

FingerprintJS read 'Chromium-Based Browser Not Available' for our engine. We blamed the version; the real variable was Google's branding.

![Chrome versus Chromium, each name in its own tile: Same version, one name missing](https://mosaicbrowser.com/covers/fingerprintjs-cannot-name-browser.webp)

The FingerprintJS demo reads "Chromium-Based Browser Not Available" when it can tell a browser is built on Chromium but cannot match it to a named product. For months we read that line on our own engine as a database lag, because Google's own unbranded build of the same version got the identical string. Then branded Google Chrome of that same version was named exactly, and the excuse fell apart. The variable was never the version. It was Google's branding.

## When FingerprintJS reads "Chromium-Based Browser Not Available"

FingerprintJS is the commercial identifier many sites actually deploy, so its demo at fingerprint.com is a row in our detection catalogue. For a long stretch our engine, Tesseract Chrome, came back as:

```
Chromium-Based Browser Not Available on Mac OS X (10.15.7)

```

where the Google Chrome on the same Mac read `Chrome 152.0.0 on Mac OS X`.

The identification itself was fine. The demo issued a visitor ID, and its confidence read 0.99 to 1.0, the same as stock. Only the name failed to resolve. That made it easy to treat as cosmetic, and that was a mistake: a commercial identifier that cannot say "Chrome" about a browser claiming to be Chrome has noticed something.

## The excuse, and why it looked solid

We had a control. We ran Google's own Chrome for Testing 153.0.8010.36, unmodified, through the same demo from the same machine, and it returned the byte-identical string. An untouched Google build doing exactly what ours did is normally the end of the question: the verdict is about the site, not the profile.

So the conclusion was written down as "their database has not ingested 153 yet", and the exemption was pinned to that version, set to expire on its own when the engine moved past 153.

Along the way we did fix real things. Our client hints had reported the full version as a bare `153`, which no Chrome does; sending the full build number moved FingerprintJS's confidence from 1 to 0.99, which is stock's exact figure. We also tried the obvious suspects and ruled them out by measurement: Widevine made available, a 153/152/153 sweep of the claimed version on one profile, the client-hint metadata. The name did not move.

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)

## The control that was measuring something else

The control was taken while the Google Chrome on that Mac was still 152. The only 153 we had to compare against was Chrome for Testing, and Chrome for Testing is unbranded. So in our table, version and branding were one column, and we gave the credit to the wrong one.

Chrome updating itself to 153 split them:

| Browser | FingerprintJS |
| --- | --- |
| Google Chrome 152, branded | Chrome 152.0.0 |
| Google Chrome 153.0.8010.52, branded | Chrome 153.0.0, confidence 0.93 |
| Chrome for Testing 153, unbranded | Chromium-Based Browser |
| Chrome for Testing 153, field-trial config off | Chromium-Based Browser |
| Our engine 153, all switches on | Chromium-Based Browser |

Two 153 binaries, opposite verdicts. The demo separates branded Google Chrome from unbranded Chromium, and it treats Google's own unbranded build exactly as it treats ours. IPHey was doing the same thing with its browser signal at the time, which is the other half of this story in [IPHey's whale signal](https://mosaicbrowser.com/blog/iphey-whale-signal).

The control had a second flaw we found later. Chrome for Testing lists `Chromium/153` in its brand list while its User-Agent says `Chrome/153.0.0.0`, so it contradicts itself, and a browser that contradicts itself cannot vouch for anyone else. Our engine launched without its brand switches has the same contradiction for the same reason. "The raw Google build fails too" was circular both times.

## What we ruled out, one variable at a time

The fourth row of that table is the one worth having. `--disable-field-trial-config` had just removed twenty API-surface differences between our build and Chrome, so it was the obvious candidate, and it moved neither FingerprintJS nor IPHey. The twenty entries are in [twenty APIs Chrome lacks](https://mosaicbrowser.com/blog/twenty-apis-chrome-lacks); they were a real fix, just not this one.

The brand claim was ruled out too. `navigator.userAgentData.brands` and the User-Agent were byte-identical to branded Chrome's on the same origin: `Google Chrome/153`, `Not_A Brand/8`, `Chromium/153`. And a profile claiming 152, with the User-Agent and the client hints both moved, did not change the verdict.

So we stopped calling it a lag. The version gate came out of the code, because gating on the version was the wrong idea from the start: on 154 it would have expired, reopened two investigations and pointed them at something that was not the cause. The row was reported as needing attention, with the reason and the command that re-tests it, never as a pass.

## Nineteen voices only Chrome lists

The largest branding difference a page can read turned out to be the speech voice list. `speechSynthesis.getVoices()` returned 199 entries in branded Chrome on our Mac and 180 in any unbranded build of the same version. The 180 are macOS's own voices and matched exactly. The other 19 are Google's network voices, `Google US English`, `Google Deutsch` and seventeen more, supplied by a component extension that is built in only when Chromium is compiled as Google Chrome.

One call with no permission reads the whole list. A User-Agent claiming Chrome beside a Chromium-sized voice list is not an ambiguity; it is an answer to the exact question this demo was failing to answer. Our comparison script had read that field and missed it, because it read the list before it filled in, got 0 from both browsers and called them equal; that part is in [199 voices](https://mosaicbrowser.com/blog/chromium-speech-voices).

Patch `0145-branded-tts-voices` puts the 19 back where Chrome's own would arrive, in Chrome's order, with names recorded from a branded Chrome on the same machine. We are not claiming here that this alone makes the demo print "Chrome". What we can say is narrower: of the differences we measured between a branded and an unbranded build of one version, the voice list was the larger part, and it no longer differs.

## What to take from it if you run your own checks

An excuse is only as good as the thing it controlled for. Ours had the right evidence and the wrong explanation, for as long as the machine happened to be one Chrome release behind. If FingerprintJS cannot name your Chromium-based browser, compare it with branded Google Chrome of the same version, not with Chrome for Testing or another Chromium build, because those share the very thing you are trying to find. How Mosaic draws the rest of a profile so its values agree with each other is on [real fingerprints](https://mosaicbrowser.com/features/real-fingerprints).

## Questions

### What does 'Chromium-Based Browser Not Available' mean on the FingerprintJS demo?

The demo recognised a Chromium browser but could not match it to a named product such as Chrome. In our measurements every unbranded build of Chromium got it, including Google's own Chrome for Testing, while branded Google Chrome of the same version was named.

### Is it because my Chrome version is too new for their database?

That was our first explanation and it was wrong. Branded Google Chrome 153 was named 'Chrome 153.0.0' while Chrome for Testing 153 and our engine 153 were not. Same version, different answer, so the version was not the cause.

### Does the message mean FingerprintJS failed to identify me?

No. In our runs the demo still issued a visitor ID with a confidence of 0.99 to 1.0, the same as stock Chrome. Only the browser's name could not be resolved.

### What separates branded Chrome from Chromium that a page can read?

The biggest difference we found was the speech voice list: 199 voices in branded Chrome on our Mac and 180 in any unbranded build, because 19 Google network voices ship only with Google's branded build. The other was about twenty API entries a non-branded build turns on through its field-trial config.

## Related

[199 voices: how a speech list tells Chromium from Chrome](https://mosaicbrowser.com/blog/chromium-speech-voices): speechSynthesis.getVoices() lists 199 voices in Google Chrome on our Mac and 180 in any unbranded Chromium. A page reads the difference in one call.

[IPHey's "(whale)" signal, and what it was really about](https://mosaicbrowser.com/blog/iphey-whale-signal): IPHey's inconsistent browser fingerprint (whale) looked like a version problem. We followed it through branding and JavaScript to a Widevine certificate.

[Twenty APIs Chrome doesn't have: Chromium's field trials](https://mosaicbrowser.com/blog/twenty-apis-chrome-lacks): Unbranded Chromium runs its field-trial testing config at every launch. Against Chrome 153 that was 20 API differences, and one switch moved them all.

[Machines that exist: fingerprints drawn from real hardware](https://mosaicbrowser.com/features/real-fingerprints): Mosaic draws each profile's GPU, screen, CPU, memory and fonts from one real device, so the parts of a fingerprint agree with each other and with the host.

[A detector that never answered because its tab was in the background](https://mosaicbrowser.com/blog/requestanimationframe-background-tab): Background tab throttling stops requestAnimationFrame. Our test tab was in the background, two detectors never answered, and Page.bringToFront fixed both.

[Pixelscan's masking verdict, bisected to one surface](https://mosaicbrowser.com/blog/pixelscan-masking-bisected): We bisected Pixelscan's masking detected verdict on one profile. Canvas, WebGL, audio and client rects were fine. Hiding about 2% of font families caused it.

[The canvas method nobody noised: what a worker test found](https://mosaicbrowser.com/blog/the-canvas-method-nobody-noised): Our canvas noise reached toDataURL and missed toBlob, so a page calling toBlob got a PNG byte-identical to stock Chrome's. A worker test caught it.



## 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.
