google/gson · error · MalformedJsonException
JSON forbids NaN and infinities: ${d}; at path ${in.getPrevi
Error message
JSON forbids NaN and infinities: ${d}; at path ${in.getPreviousPath()} What it means
Thrown by the LONG_OR_DOUBLE ToNumberStrategy when a JSON numeric token parses to Double.NaN or Double.POSITIVE/NEGATIVE_INFINITY and the JsonReader is NOT in lenient mode. Standard JSON forbids NaN and infinities, so Gson rejects them in strict/legacy mode. The message includes the offending value and the JSON path.
Source
Thrown at gson/src/main/java/com/google/gson/ToNumberPolicy.java:88
@Override
public Number readNumber(JsonReader in) throws IOException, JsonParseException {
String value = in.nextString();
if (value.indexOf('.') >= 0) {
return parseAsDouble(value, in);
} else {
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
return parseAsDouble(value, in);
}
}
}
private Number parseAsDouble(String value, JsonReader in) throws IOException {
try {
Double d = Double.valueOf(value);
if ((d.isInfinite() || d.isNaN()) && !in.isLenient()) {
throw new MalformedJsonException(
"JSON forbids NaN and infinities: " + d + "; at path " + in.getPreviousPath());
}
return d;
} catch (NumberFormatException e) {
throw new JsonParseException(
"Cannot parse " + value + "; at path " + in.getPreviousPath(), e);
}
}
},
/**
* Using this policy will ensure that numbers will be read as numbers of arbitrary length using
* {@link BigDecimal}.
*/
BIG_DECIMAL {
@Override
public BigDecimal readNumber(JsonReader in) throws IOException {
String value = in.nextString();View on GitHub (pinned to 310ac341f2)
Solutions
- Switch to ToNumberPolicy.LAZILY_PARSED_NUMBER or ToNumberPolicy.DOUBLE which handle special values without this guard
- Set the JsonReader to Strictness.LENIENT if the source legitimately uses NaN/Infinity
- Fix the data source to emit valid JSON numbers (null for NaN/Infinity, or string representations)
Example fix
// before gsonBuilder.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE); // after gsonBuilder.setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER);
Defensive patterns
Strategy: validation
Validate before calling
// Check for NaN/Infinity literals before deserializing with LONG_OR_DOUBLE
String raw = jsonNode.get("value").getAsString();
if ("NaN".equals(raw) || "Infinity".equals(raw) || "-Infinity".equals(raw)) {
// decide: coerce to null, use Double, or reject
return null;
} Try / catch
try {
return gson.fromJson(json, type);
} catch (MalformedJsonException e) {
if (e.getMessage().contains("forbids NaN")) {
// switch to a lenient reader or LAZILY_PARSED_NUMBER strategy
return parseLenient(json, type);
}
throw e;
} Prevention
- If your data source emits NaN/Infinity, use ToNumberPolicy.DOUBLE or LAZILY_PARSED_NUMBER instead of LONG_OR_DOUBLE
- Set JsonReader strictness to LENIENT if non-standard number literals are expected
- Validate number fields from untrusted sources before deserialization
When it happens
Trigger: Deserializing numbers using ToNumberPolicy.LONG_OR_DOUBLE (set via GsonBuilder.setObjectToNumberStrategy or setNumberToNumberStrategy) where the JSON contains the literals NaN, Infinity, or -Infinity, and the reader strictness is not LENIENT.
Common situations: Non-JSON-compliant APIs or legacy systems that emit NaN/Infinity; switching the number strategy to LONG_OR_DOUBLE without checking source data; scientific/financial feeds using non-standard number tokens.
Related errors
- Cannot parse ${value}; at path ${in.getPreviousPath()}
- String contains non-ASCII characters: ${s} at path ${path}
- cannot deserialize ${baseType} because it does not define a
- cannot deserialize ${baseType} subtype named ${label}; did y
- Failed to parse date [${input}]: ${fail.getMessage()}
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/5635c080b1116bc7.
Report an issue: GitHub.