NaN and Infinity in JSON

The JSON number grammar covers an optional minus sign, digits, an optional fraction and an optional exponent. NaN, Infinity and -Infinity match none of that, and JSON has no literal for them.

How the message appears

The same fault, worded by different engines. V8 (Chrome, Node, Edge) changed its format around Chrome 109, so older and newer runtimes disagree about the same document.

  • SyntaxError: Unexpected token 'N', ..."value": NaN}"... is not valid JSON
  • SyntaxError: JSON.parse: unexpected character at line 1 column 11 of the JSON data

The fix

Use null for a value that has no number, and say so in your schema. If the distinction matters, encode it explicitly as a string ("NaN") and convert on read.

Fails to parse
{
  "ratio": NaN,
  "limit": Infinity
}
Parses
{
  "ratio": null,
  "limit": null
}

The example travels in the URL fragment, which browsers never send to a server.

What causes it

A serializer that emits the language’s own literals

Python’s json.dumps writes NaN and Infinity by default, which is valid Python and invalid JSON. Pass allow_nan=False to make it raise instead of producing a document other parsers reject.

A division or parse that produced NaN upstream

0/0, parseFloat("abc") and arithmetic on undefined all yield NaN. In JavaScript it then silently becomes null in the output, which is usually the real bug: a missing value that reads as a deliberate one.

Floating-point overflow

A number past roughly 1.8 × 10^308 becomes Infinity in IEEE-754 double precision. Very large integers hit a related problem: past 2^53 they lose precision silently on parse.

Worth knowing

  • JavaScript already does this for you: JSON.stringify({a: NaN}) returns {"a":null} rather than throwing.
  • JSON.stringify also drops undefined object properties entirely and converts undefined array elements to null, so an array can change meaning without changing length.

Written by Vishnu Shankar.

Your JSON and text are processed entirely in your browser and are never sent anywhere. To understand how the site is used we record each page view (the page, the referrer and an approximate location from your IP address) and keep it for 90 days. Nothing is stored on your device unless you choose it. Accept to also store a device identifier here and record your browser and device characteristics, which is what lets a return visit be told from a new one. Decline and nothing is sent at all. We respect Do Not Track. See our privacy policy.