Blog / Fingerprinting explained

Fingerprint consistency: why mismatched values give a browser away

Why detection systems care more about contradictions than rare values, the eight mismatches they check most, and console snippets to check each one yourself.

By Charles Lee · 6 min read

A browser fingerprint is inconsistent when two of its values could not both be true on a real device: a Mac user agent with Windows fonts, a Tokyo timezone with a clock set to London, a page that reports eight processor cores while its own Web Worker reports four. Detection systems look for these contradictions because real hardware does not produce them. One mismatch says more than any rare value.

This post explains why consistency beats rarity, goes through the eight contradictions that are checked most often, gives you a short console snippet to check each one in your own browser, and shows how Browz keeps a profile's values in agreement.

Rare is normal, contradictory is not

Fingerprints are usually explained in terms of uniqueness: how few other browsers share your exact combination. That is the right lens for tracking. For deciding whether a browser is telling the truth about itself, it is the wrong one.

Plenty of real people have unusual setups: a large monitor, a rare language pair, a workstation GPU. A detection model trained on millions of real visits has seen all of those. What it has not seen, because it cannot happen, is a value that disagrees with another value from the same machine. A rare value lowers confidence slightly. A contradiction is close to proof that something changed the browser's answers.

That is why changing a fingerprint by editing individual values tends to make a browser more conspicuous, not less. Every value you change has neighbours it must still agree with.

The eight contradictions checked most often

Open your browser's developer console (on most browsers, F12 or Cmd+Option+J) on any ordinary page to run the snippets below. They only read values; they change nothing.

1. Timezone against the IP address

Sites look up the location of your IP address on every request and compare it with the timezone your browser reports. A browser in Frankfurt that keeps Sydney time is the most common mismatch behind a proxy or VPN.

jsIntl.DateTimeFormat().resolvedOptions().timeZone

Compare the answer with where your IP address exits. Also check the clock agrees with the zone: new Date().getTimezoneOffset() returns minutes behind UTC, so Sydney in summer reads -660.

2. Languages against the locale and region

Your language list, the first language and the locale used to format dates should agree with each other, and should be plausible for the region of your IP address.

js[navigator.languages, Intl.DateTimeFormat().resolvedOptions().locale]

A list that starts de-DE while dates format as en-US suggests the language was changed in one place only. A mismatch with the IP's country is weaker on its own, since many people browse in a second language.

3. User agent against client hints

Chrome-based browsers describe themselves twice: in the user agent string and in client hints, a structured copy sent in request headers and available to scripts. A user agent changed by an extension often leaves the hints untouched.

jsnavigator.userAgentData.getHighEntropyValues(['platform', 'platformVersion', 'fullVersionList']).then(console.log)

The platform and the major version here should match navigator.userAgent. We cover this pair in depth in user agent and client hints.

4. Screen against the device

A screen of 1366 × 768 at a pixel ratio of 1 is ordinary on a budget Windows laptop and never seen on the built-in display of a recent Mac. The window also cannot be bigger than the screen, and the available area cannot be bigger than the screen either.

js[screen.width, screen.height, screen.availWidth, screen.availHeight, devicePixelRatio, outerWidth, outerHeight]

5. CSS against JavaScript

Media queries in CSS read the screen through a different path from scripts. If a script layer changed screen.width but not the engine, CSS still sees the real display.

js[matchMedia(`(device-width: ${screen.width}px)`).matches, matchMedia(`(resolution: ${devicePixelRatio}dppx)`).matches]

Both should be true.

6. Graphics and fonts against the operating system

The WebGL renderer string usually names the graphics API underneath, and each API belongs to one operating system: Direct3D on Windows, Metal on Apple systems. Fonts are similar: every operating system ships its own set.

js(() => { const gl = document.createElement('canvas').getContext('webgl'); const d = gl.getExtension('WEBGL_debug_renderer_info'); return gl.getParameter(d.UNMASKED_RENDERER_WEBGL); })()

A Mac user agent with a Direct3D renderer, or with only Windows fonts, cannot occur on real hardware.

7. The page against its workers and iframes

A Web Worker runs on its own thread with its own navigator. A script that changed values in the page has to reach every worker and every new iframe too, in time, or they report the originals.

jsnew Worker(URL.createObjectURL(new Blob(['postMessage([navigator.userAgent, navigator.hardwareConcurrency, navigator.languages])']))).onmessage = (e) => console.log(e.data, [navigator.userAgent, navigator.hardwareConcurrency, navigator.languages])

The two arrays should be identical.

8. A value against itself, over time

Real hardware draws the same canvas image every time. A browser that adds random noise returns a slightly different hash on each read, and a fingerprint ID that changes on every visit while everything else stays put is its own signal. Reading twice on one page is enough to see it.

How to check all of them at once

Running snippets one by one is useful for understanding. For a quick verdict, our free browser fingerprint test runs fifteen of these comparisons in a couple of seconds, including the page-versus-worker, page-versus-iframe and stable-readings checks, and explains each result in a sentence. It runs entirely in your browser and sends nothing. For a guided reading of every row, see how to test your browser fingerprint.

Two things a page cannot check are your IP address and your TLS handshake, both of which a server sees. For the first, compare your timezone and languages with the country of your exit by hand. For the second, the browser's own network stack has to be left alone.

Fixing a mismatch

Most contradictions come from one of four causes:

  • An extension or script that changes one value. Remove it, or replace it with a setup that changes values at the source.
  • A proxy or VPN without matching time and language. Set the timezone and languages to the exit's region, or use a browser that sets them from the exit for you.
  • An emulated device on the wrong hardware. Present a device type that fits the machine underneath, or leave screen, CPU and memory real.
  • Random noise. Turn it off. Stable values are what real devices have.

How Browz keeps a profile consistent

Browz is built around the idea that a profile should be one believable device, not a collection of individually changed values.

  • Values derived together. Each profile's platform, screen, fonts, graphics names, voices and languages are derived together from a real device type and a seed, so they agree with each other, and they stay the same between sessions. Each surface can be Auto, Custom or Real on the engines page.
  • Coherence warnings. If you set a surface by hand in a way that contradicts another, Browz warns you, so the slip is caught in the app rather than by a site.
  • Time and place from the exit. A profile's timezone, languages and geolocation follow its proxy's measured exit, and with launch guards on, Browz refuses to start a profile whose exit moved to another country or whose timezone the readings dispute. More on this in matching timezone and location to a proxy.
  • One answer everywhere. Values are set in the engine's own code, so the page, its workers, its iframes and the request headers agree, CSS sees what JavaScript sees, and the user agent and client hints match the version the profile really runs.
  • No noise by default. Each profile draws text in its own small, stable way, so canvas images differ between profiles but stay identical between two reads.

On 13 November 2026, Browz 0.1.9 on macOS passed 15 of 15 consistency checks in our fingerprint test, in a normal window and headless, and the same test found no inconsistencies on Windows or Linux. The result and raw JSON are on the anti-detect page.

Frequently asked questions

What is a fingerprint mismatch?

It is two values from the same browser that could not both be true on a real device, such as a Windows user agent with Mac fonts or a timezone that disagrees with the clock. Detection systems treat a mismatch as a stronger sign of a changed browser than any single unusual value.

Can a timezone mismatch with my IP get me flagged?

It is one of the signals sites weigh, alongside many others. Travellers have mismatches too, so it rarely decides anything alone, but combined with other contradictions it adds up. Matching the timezone and languages to the exit's region removes the question.

Why do privacy extensions cause inconsistencies?

Most of them work by changing values from inside the page with JavaScript. The headers, Web Workers, fresh iframes and CSS are not always reached, so the changed values disagree with the untouched ones. The protection is real, but it is visible.

Is a unique fingerprint a problem?

For tracking, uniqueness is what lets a site recognise you without cookies. For detection, it matters much less than consistency: many real devices are unusual, but none contradict themselves. Separate profiles, each with its own consistent fingerprint, address both.

Get started

Every account, every agent. Its own browser.

For Mac, Windows and Linux. Free for 5 profiles.