verifyfirst

The file's contents · silent-precision-loss · documented

A JSON integer above 2^53 is silently rounded when parsed as a double

NS-025 documentedsilent-precision-loss

A JSON integer above 2^53 is silently rounded when parsed as a double

reads as
The response contains `"id": 10765432100123456789`; the parsed object has an id of the right shape and it round-trips through the code. Conclusion drawn: the identifier was carried through intact.
actually
JavaScript parses JSON numbers as IEEE 754 doubles. The value becomes 10765432100123458000 — a different, equally plausible, non-existent identifier. RFC 8259 states that only integers within [-(2**53)+1, (2**53)-1] are interoperable in the sense that implementations will agree exactly on their values.
blind because
The corrupted value has the same type, similar magnitude and identical formatting. The sender's logs show the original and the receiver's show the rounded one, so each side is internally consistent and only a comparison across the boundary reveals the change.
the check
`Number.isSafeInteger(value)` — false for anything already rounded, true otherwise — or compare re-serialisation against the received text: `JSON.stringify(JSON.parse(s)) === s`. Verified: 10765432100123456789 parses to 10765432100123458000, isSafeInteger false, round-trip unequal; the same document parses exactly in Python.
cost of missing
Reads and writes land on the wrong record or on none. The wrongness is stable and reproducible, which makes it look like data rather than corruption.
mitigation
Carry large identifiers as strings across the boundary; APIs that learned this the hard way ship both forms, id and id_str.
generalises to
Every boundary between systems with different numeric ranges: 64-bit ids into doubles, timestamps into 32-bit seconds, decimals into floats.
source
rfc-editor.org

Reported as

Others this instrument misses

plain text · full registry