google/gson · error · MalformedJsonException
JSON forbids NaN and infinities: {result}
Error message
JSON forbids NaN and infinities: {result} What it means
JsonTreeReader.nextDouble throws MalformedJsonException('JSON forbids NaN and infinities: ' + result) when the parsed double value is NaN or +/-Infinity AND the reader is not lenient. Strict JSON (RFC 8259) does not permit NaN or Infinity literals; only lenient mode tolerates them. The {result} is the offending numeric value.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/JsonTreeReader.java:254
}
}
@Override
public double nextDouble() throws IOException {
JsonToken token = peek();
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
throw new IllegalStateException(
"Expected " + JsonToken.NUMBER + " but was " + token + locationString());
}
JsonPrimitive primitive = (JsonPrimitive) peekStack();
double result;
try {
result = primitive.getAsDouble();
} catch (NumberFormatException e) {
throw numberFormatException("Expected a double but was " + primitive.getAsString(), e);
}
if (!isLenient() && (Double.isNaN(result) || Double.isInfinite(result))) {
throw new MalformedJsonException("JSON forbids NaN and infinities: " + result);
}
popStack();
if (stackSize > 0) {
pathIndices[stackSize - 1]++;
}
return result;
}
@Override
public long nextLong() throws IOException {
JsonToken token = peek();
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
throw new IllegalStateException(
"Expected " + JsonToken.NUMBER + " but was " + token + locationString());
}
JsonPrimitive primitive = (JsonPrimitive) peekStack();
if (token == JsonToken.STRING) {
validateAscii(primitive.getAsString());View on GitHub (pinned to 8b8628c656)
Solutions
- Enable lenient mode: construct the JsonReader and call setLenient(true) before reading (note: Gson.fromJson defaults are strict).
- Sanitize the source: replace NaN/Infinity with null or a sentinel value before building the tree.
- Register a custom TypeAdapter for double/Double that converts NaN/Infinity to null or a defined sentinel on write and accepts it on read.
- Validate upstream that the producer never emits NaN/Infinity.
Example fix
// before
JsonObject o = new JsonObject(); o.addProperty("v", Double.NaN);
JsonTreeReader r = new JsonTreeReader(o);
r.beginObject(); r.nextName();
r.nextDouble(); // MalformedJsonException: JSON forbids NaN and infinities: NaN
// after
JsonTreeReader r = new JsonTreeReader(o);
r.setLenient(true);
r.beginObject(); r.nextName();
r.nextDouble(); // returns NaN Defensive patterns
Strategy: validation
Validate before calling
// Sanitize NaN/Infinity in source doubles before building the tree
double sanitize(double v) {
return Double.isNaN(v) || Double.isInfinite(v) ? 0.0d : v; // or use null wrapper
} Type guard
static boolean isJsonLegalDouble(double v) {
return !Double.isNaN(v) && !Double.isInfinite(v);
} Try / catch
JsonReader r = new JsonTreeReader(element);
r.setLenient(true); // opt-in to NaN/Infinity if the source may contain them
try {
return r.nextDouble();
} catch (MalformedJsonException e) {
if (e.getMessage() != null && e.getMessage().startsWith("JSON forbids NaN and infinities")) {
throw new InvalidPayloadException("Numeric value not representable in strict JSON", e);
}
throw e;
} Prevention
- Filter NaN/Infinity at the producer when emitting strict JSON.
- Enable setLenient(true) only on readers where non-standard numbers are expected.
- Use a sentinel (null or a flag) instead of NaN/Infinity in JSON contracts.
When it happens
Trigger: Reading a JsonPrimitive holding Double.NaN, POSITIVE_INFINITY, or NEGATIVE_INFINITY through a non-lenient JsonTreeReader.nextDouble(). Common when the source tree was built from a Java object that had NaN/Infinity doubles and then re-serialized strictly.
Common situations: Math/finance code producing NaN or Infinity; sensor data with NaN sentinels; deserializing a tree that a lenient writer produced back through a strict reader; default Gson is non-lenient.
Related errors
- Expected NUMBER but was {token}{location}
- JsonReader is closed
- Expected {expected} but was {peek}{location}
- Expected STRING but was {token}{location}
- Primitive is neither a number nor a string
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/d91c9cf9d8a20222.json.
Report an issue: GitHub.