typefaces the claimed OS ships as separate faces measure as separate faces
Check id claimed-os-typefaces-are-distinct
What an ordinary browser yields
Every probed typeface belonging to the claimed operating system measures a distinct advance width, because separate faces have separate metrics. Declined entirely under a Linux claim, which ships no universal face set, and declined when the metrics are flattened or a nonexistent face resolves.
What a detector infers
A font request is answered by the host's font stack, not by the browser and not by anything the user agent sets, so changing navigator.platform does not move a single glyph. That makes the font layer an OS oracle — but the obvious way to read it does not work, and the reason is worth stating because it is what shapes this check. Asking whether a named Windows face such as Segoe UI or Calibri is INSTALLED returns yes on a Linux machine that has none of them: fontconfig ships metric-compatible substitutions, mapping Calibri to Carlito and Cambria to Caladea, and those clones are built to match the original's advance widths exactly. Measured on stock Chromium on Linux, Calibri and Carlito both render a probe string at 853.559px, and Segoe UI returns 914.273px — the identical value a real Windows Chrome returns. A substitute designed to match the original's metrics cannot be detected by measuring the original's metrics, so no width table and no presence test can see it. What a substitution scheme cannot do is provide a distinct clone for every face. Faces without one fall back to the platform default and therefore collide WITH EACH OTHER: on that same Linux host, Tahoma and Arial both measure 905.203px, because Tahoma has no substitute and lands on the default sans-serif that Arial already maps to. On Windows those are two different typefaces and cannot share an advance width. So this row asks a self-referential question — do faces the claimed operating system ships as SEPARATE typefaces actually measure separate here — and it carries no expected widths at all, which is what keeps it from rotting when a font version changes. Two refusals are built in and both were measured rather than reasoned about. First, collapse onto a generic is never scored: on Windows Chrome the default monospace IS Consolas and the default sans IS Arial, so `Consolas === monospace` and `Arial === sans-serif` are true on a genuine Windows machine, and a check reading that as a missing font would fail every real Windows browser. Only collisions between two non-default named faces count. Second, a browser that defeats font enumeration flattens every metric, and pervasive collision is that defence rather than an OS lie — so the row requires a majority of the probed set to be mutually distinct before it will assert, and declines on a flattened palette. A face that does not exist is probed as a control; if it resolves to its own metrics the browser is answering synthetically and the whole reading is discarded.
How to resolve it
Font metrics come from the host's font stack, below anything the user agent controls, so a persona presenting another operating system carries the wrong ones no matter what it reports. A metric-compatible substitute hides the faces it covers — that is its purpose — but it cannot cover the whole set, and two different typefaces answering with one advance width means one of them fell back. The complete answer is to run on the operating system being claimed; a captured font profile is the partial one, and it has to supply the entire face set rather than the few names an open substitute package happens to clone.
Read in the wild by
FingerprintJS
Its open-source font entropy source measures a probe string in each candidate face against the three generic base fonts and treats a difference in width or height as the face being present. That is the same measurement this row takes; the difference is what is done with it. FingerprintJS keeps the resulting presence vector as an identifier, whereas this row discards it — because, as measured here, the presence answer is wrong on Linux for exactly the faces a Windows persona would be asked about — and reads only whether two faces collide with each other.
src/sources/fonts.ts: a fixed font list measured span-by-span against monospace, sans-serif and serif base fonts, presence recorded when the rendered size differs from the base.
FingerprintJS (open-source agent)Clearcote (measured)
Not a sighting of a vendor reading it, but the measurement that motivated the row, and the product's own documentation agrees. The SDK prints an unprompted warning when a Windows persona is requested on a Linux host: font, canvas and font-list hashes will be host-native and will not match a real Windows Chrome. Measured against that build, every probed font width under platform="Windows" was byte-identical to stock Chromium on the same host — the persona does not touch the font layer at all, exactly as the warning says.
Clearcote PRO 150.0.7871.114 on Linux, platform="Windows": Tahoma 905.203 = Arial 905.203 (collision); identical widths to stock Chromium on the same host across all probed faces. Real Windows headed Chromium: six named faces, zero pairwise collisions.
clearcote SDK launch warnings (_warnings.py)Every attribution traces to a published artifact. See the sources and their limits.
Other checks in Engine & OS oracles
- The measured JS engine matches the engine the User-Agent claims
js-engine-identifier-vs-uaTwo values are read straight out of the JavaScript engine itself: the character length of the RangeError message thrown by (-1).toFixed(-1)… - Math.tanh rounds the way the claimed OS's libm rounds
math-tanh-os-vs-uaIEEE 754 fixes how a double is stored but does not require transcendental functions to be correctly rounded, so every operating system's C… - which OS hyphenation engine the browser hyphenates through
hyphenation-engine-osWhen CSS asks a browser to hyphenate a long word, the break points come from a dictionary supplied by the operating system — and the… - the CPU architecture matches the architecture the browser claims
cpu-arch-nan-vs-uachIEEE-754 fixes the exponent and the quiet bit of a NaN but leaves the sign bit to the hardware, and the hardware disagrees: an x86 FPU… - the three heap numbers describe a possible heap
jsheap-triplet-orderingThis check replaces a retired one, and the swap is the lesson. - the platform's system font belongs to the operating system claimed
system-font-vs-claimed-osThe CSS2 system-font keywords — caption, icon, menu, message-box, small-caption and status-bar — are resolved by the HOST platform's font…
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 Engine & OS oracles 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 Engine & OS oracles — the family claimed-os-typefaces-are-distinct belongs to.