A geolocation spoofing timeout is what our engine shipped until 4 October 2026. A profile behind a Lisbon exit answered its first getCurrentPosition with coordinates near the exit, then failed every call after it with error code 3, TIMEOUT. A watch started after that one-shot timed out too. The first answer was right, and that is why nobody saw the bug: every manual test is a first call.

It was reported as missing

The report said geolocation did not work. It did. Patch 0114-geolocation has implemented the --fingerprint-location switch since the first build of the engine, and the launcher draws the coordinates from the profile's measured exit. On the Lisbon profile the page received 38.73076,-9.36132 against an exit at 38.6875,-9.3151, a few kilometres apart, which is what we intend.

So we asked the page a second time. It waited, and then it failed with code 3. So did the third call, and the fourth. A watch opened after the one-shot never received a position either.

Every profile is drawn from one real computer, not from separate listsIn Mosaic: Machines that exist. GPU, screen, CPU and fonts from one real device. Free holds 3 profiles. Pro is $49 a month for any number.

How it works: Machines that exist

Why the geolocation spoof timed out: a latch never cleared

A position watch in Chromium asks for the next position after it delivers one. If our patch answered that request every time, a watch would spin forever, handing the page the same fix in a tight loop. So the patch sets a flag, fingerprint_position_sent_, once it has delivered a fix, and stays quiet after that.

The flag was correct. Nothing ever cleared it. The comment beside it argued that one fix and then silence "is what a real device reports when it has not moved". That holds for a watch. A phone that has not moved stops sending new watch events. It does not hold for a fresh getCurrentPosition: a phone sitting still on a desk still answers every time a page asks.

The fix is one line in StartRequest. That function is reached only by getCurrentPosition, by watchPosition, and by the page becoming visible again, and each of those is a request nobody has answered yet. The watch's own follow-up request arrives by a different path, UpdateGeolocationState, and still hits the latch, so the loop stays closed.

A Mosaic profile fingerprint with timezone, language and geolocation drawn for the exit
Geolocation is drawn from the exit, like the timezone

Why answering once is worse than not answering

A browser that refuses geolocation is ordinary. Many people say no to the prompt, and many sites never ask. A browser that answers once and then times out for ever matches no real device. A site that polls position, as delivery maps and store finders do, reads that pattern without trying to.

And the pattern sits on the surface the patch was written to protect. The point of claiming the exit's coordinates in C++, rather than in page JavaScript (we explain that choice in C++, not JavaScript), is that the browser behaves like one machine in one place. Half-working behaviour gave away more than the real coordinates would have.

What the check holds now

check:geolocation launches the engine with a location nowhere near our Mac and asks four questions:

  1. Five getCurrentPosition calls in a row: all five answer.
  2. A watch opened after a one-shot: it answers.
  3. A standing watch over six seconds: exactly one update, because the profile has not moved.
  4. The claimed coordinates: they arrive in the page.

Before calling the fix done we put the bug back, rebuilt the engine and ran the check against it. It reported 1 of 5 consecutive getCurrentPosition calls answered and named the watch pairing, while the first read still returned the test coordinates. A check that asks a second time is the one this bug needed.

The jitter we kept small

While we were in that code, we were asked for the coordinates to be moved by about 50 kilometres instead of the ±0.05 degrees (roughly 5 km) they move now. We kept 5 km. Fifty kilometres takes a point outside the metropolitan area the IP itself resolves to, and our own realignment already treats more than 0.5 degrees from the exit as a mismatch worth correcting. A bigger jitter would create the disagreement the feature exists to prevent. Five kilometres is enough that no two profiles share a point and none reports the computer's exact position.

How the coordinates fit with the timezone, language and the rest of the machine is on real fingerprints, and the list of values a page can read is in browser fingerprint. The question to ask of every one of them is the one that found this bug: does it work twice?