Can NaN or Infinity appear in JSON
Bottom line: JSON has only decimal number literals. JSON.stringify turns NaN and Infinity into null without warning, which is why "the number field is sometimes null" keeps showing up in production.

Bottom line: JSON cannot represent NaN or Infinity — JSON.stringify silently turns both into null — so encode the state explicitly with null plus a reason field, or a documented string value.
JSON.stringify({ ratio: NaN, limit: Infinity });
// '{"ratio":null,"limit":null}'
No error, no warning. Two numbers become null.
What the grammar allows
number = [ minus ] int [ frac ] [ exp ]
Decimals only. NaN and Infinity are IEEE 754 sentinels, not literals. Written into JSON they are invalid identifiers, and since their comparison semantics differ across languages, the spec excludes them rather than picking a representation.
What each language does instead
| Language | Behaviour |
|---|---|
JavaScript JSON.stringify |
Silently emits null |
Python json.dumps |
Emits NaN by default (non-standard); raises with allow_nan=False |
Go encoding/json |
Returns unsupported value: NaN |
| Java Jackson | Emits the string "NaN" by default |
Four behaviours for one value. When a cross-language API shows a number field that is intermittently null, check this layer first.
What to do instead
Documented strings. "NaN", "Infinity" with a type note. Costs every consumer an explicit check.
null plus a status field. Better: {"avgLatency": null, "avgLatencyStatus": "no-sample"}. The reason travels with the value.
Rethink the unit. Most Infinity results come from dividing by zero samples. Returning null and rendering "no data yet" usually matches the business truth better than an infinite number.
Related traps
- Chart libraries break the line on
null— confirm that is what you want JSON.stringifyalso dropsundefined, functions and symbols entirely; those keys vanish rather than becomingnull- Python's default
allow_nan=Trueproduces output thatJSON.parserejects