navigator.language === languages[0]
Check id languages-coherence
What an ordinary browser yields
navigator.language is character-for-character the first entry of navigator.languages (e.g. "en-US" with ["en-US", "en"]).
What a detector infers
In a real browser navigator.language is defined as the first element of navigator.languages — one preference list, two views onto it. This check simply tests navigator.language === navigator.languages[0]. Because the engine derives one from the other, they cannot drift apart on their own; when they do, a detector infers that the two properties were assigned separately, which points at a userland override that patched one accessor and missed the other. That inference generalises: partial spoofs of paired properties are among the cheapest tells available, since the detector needs no baseline of what a normal user looks like, only the invariant. Severity is warn, and the reported detail lists both values so you can see which side drifted.
How to resolve it
Set the locale in one place so both properties are derived from it, rather than assigning language and languages independently. While you are there, keep the list consistent with the Accept-Language header and the timezone/IP region.
Read in the wild by
PerimeterX / HUMAN
Ships navigator.language, the full navigator.languages array and languages.length as three separate fields of one payload.
main.min.js (deployed collector, ifood.com.br, app PXO1GDTa7Q): `t[0][hQ(713)]=hU[hQ(843)]` (hQ(713)="EmInaFQCLVk=", hQ(843)='language'); `t[0][hQ(714)]=hU.languages` (hQ(714)="dEABCjIjCzk="); `t[0][hQ(849)]=hU.languages&&hU[hQ(850)].length` (hQ(849)="EX1kN1ceYwI=", hQ(850)='languages') — all three written onto the same t[0] object. Captured payload sample/5/decoded_payload_2.json carries all three under [0]/d/: "EmInaFQCLVk="="zh-CN", "dEABCjIjCzk="=["zh-CN","zh"], "EX1kN1ceYwI="=2.
Kasada
Reads the language list and its length, in both realms.
window_navigator_language / iframe_navigator_language, window_nav_info_lang_count / iframe_nav_info_lang_count
ips.js 427-probe teardown (emro.cat, Apr 2026)
DataDome
Ships navigator.languages verbatim.
oOdscd = "[\"en-GB\",\"en-US\",\"en\"]"
glizzykingdreko/datadome-encryption — tests/original.jsonEvery attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Navigator identity
- navigator.platform ↔ UA ↔ UA-CH platform agree
platform-coherenceThree independent surfaces each name an operating system, and this check normalises all three to one family (win / ios / mac / lin) and… - UA-CH brand version matches the UA Chrome version
uach-ua-versionThe check extracts the major from Chrome/(\d+) in the UA string, finds the Chrome or Chromium entry in navigator.userAgentData.brands, and… - UA-CH high-entropy hints cohere with the UA
uach-highentropyThis awaits navigator.userAgentData.getHighEntropyValues and compares the richer hints against the UA string on three axes, collecting every… - every brand in a UA-CH list uses the same version format
uach-brand-version-arityUA-CH publishes the same brand set twice at two precisions. navigator.userAgentData.brands carries bare majors like "148", and the… - the host voice roster represents the language the browser claims
locale-vs-voice-coherenceThe voice roster is installed at the operating-system level and the language preference is set in the browser, so the two are genuinely… - eval.toString().length matches the engine (V8 = 33)
etslThe string a JS engine returns for a native function's source is an implementation detail, and its length differs per engine… - navigator.productSub === 20030107 (Chromium)
product-subnavigator.productSub is a frozen legacy constant, not a live value: Chrome, Safari and Opera return "20030107" while Firefox returns… - a Firefox user-agent reports the Gecko productSub constant 20100101
gecko-productsub-hardcodenavigator.productSub is a constant compiled into the engine, and the two families disagree: every Gecko build hardcodes it to "20100101"…
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 Navigator identity 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 Navigator identity — the family languages-coherence belongs to.