every surface that reports when this document started agrees
Check id navigation-origin-consensus
What an ordinary browser yields
Every reachable surface — timeOrigin, the legacy timing milestones, the modern navigation entry, and chrome.loadTimes/csi where they exist — agrees about when this document started.
What a detector infers
One document has one navigation start, and Chrome exposes it through four different doors: performance.timeOrigin, the legacy performance.timing milestones, the modern PerformanceNavigationTiming entry, and the long-deprecated chrome.loadTimes() and chrome.csi(). There is one navigation timing record behind all of them, so they must agree. DataDome demonstrably holds several at once — its VM anchors its whole clock section on performance.timing.navigationStart, while the main tag independently reads the modern entry (it ships nextHopProtocol and entryType, which exist only there) and separately enumerates window.chrome's own keys to confirm loadTimes and csi are present and reachable. What makes this worth a check is what it asks that its neighbours do not. Headless patches famously re-add window.chrome.loadTimes to look like real Chrome, and a check that asks whether it exists, or whether it stringifies as native, is satisfied by a stub — this audit ships two such checks and both are honest about their limits. This one asks the stub what time the document started, and then makes three other doors check the answer. That is a question a stub can only answer correctly by doing the real work of tracking the navigation. Every arm is gated independently and contributes only if reachable, so a Chromium fork with no csi, a browser with no navigation entry, and a future Chrome that has finally removed the deprecated surfaces all degrade one arm at a time rather than failing. Two guards matter: a milestone reading 0 is the spec's did-not-happen sentinel rather than time zero, and treating it as a value flags a stock Chrome outright; and the tolerance is derived from the measured granularity of Date.now() rather than a constant, because Firefox with resistFingerprinting quantises the legacy and modern sides independently and a fixed tolerance would open a gap on a stock Tor Browser.
How to resolve it
Restore the value, not just the function. Chrome answers this question identically through four doors because one navigation timing record sits behind them; tooling hooks the door it has heard of, and the older or newer twin keeps telling the truth. Severity is a warning rather than a contradiction because Chromium forks and Android WebView ship window.chrome too, and a fork that reimplements loadTimes on a different time base is an honest browser.
Read in the wild by
DataDome
Holds several of these doors at once: its VM anchors its whole clock section on the Level-1 navigationStart, while the main tag independently reads the Level-2 navigation entry and separately enumerates window.chrome's own keys to confirm loadTimes and csi are present and reachable.
out.txt 21645 (addr 0x15a00) GET_PROP_IMM "navigationStart"; payload uKVCRV="http/1.1" (nextHopProtocol) and SYMmJy="navigation" (entryType) exist only on PerformanceNavigationTiming; O1xeSh=",loadTimes,csi,app" enumerates window.chrome
glizzykingdreko/datadome-encryption — a real 232-field captured payloadAkamai
Devotes a whole signal category to timing — navigation timing, resource timing, first paint, DOM-ready — collected per session.
analysis/signal_categories.md, section 5 "Timing Signals": Navigation timing (performance.timing entries), DOM ready timing
Edioff/akamai-analysis — Bot Manager v2 signal inventoryEvery attribution traces to a published artifact. See the sources and their limits.
Other checks in Clocks & ledgers
- the monotonic clock and the wall clock name the same instant
epoch-vs-monotonic-clockA browser carries two physically different clocks: a monotonic counter anchored at performance.timeOrigin, and the wall clock behind… - both generations of the navigation timing API describe the same page load
navigation-timing-dual-apiThe platform kept two generations of one API alive. performance.timing speaks Unix epoch; PerformanceNavigationTiming speaks milliseconds… - a stylesheet that provably loaded appears in the performance timeline
resource-timing-vs-cssomFetching a resource writes two records: the DOM object you can see, and an immutable entry in the performance timeline. - wall-clock and monotonic time advance at the same rate
wallclock-vs-monotonic-rateA browser owns two clocks and they are not the same clock. Date.now() is wall time: it can be wrong, it can be corrected, it can jump… - PerformanceEntry timestamps land on the same grid performance.now() exhibits
perf-clock-grid-coherenceA timestamp's low bits are a fingerprint. DataDome ships its performance floats unrounded — 2253.7000000029802 rather than 2253.7 — and that…
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 Clocks & ledgers 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 Clocks & ledgers — the family navigation-origin-consensus belongs to.