google/gson · error · MalformedJsonException
JSON forbids NaN and infinities: {d}; at path {in.getPreviou
Error message
JSON forbids NaN and infinities: {d}; at path {in.getPreviousPath()} What it means
In the LAZILY_PARSED_NUMBER (default) ToNumberPolicy, when a number literal parses to Double.NaN or Double.isInfinite() and the reader is not lenient, Gson throws MalformedJsonException. Standard JSON (RFC 8259) forbids NaN/Infinity, so non-lenient mode rejects them.
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 8b8628c656)
Solutions
- Set reader.setStrictness(Strictness.LENIENT) (or GsonBuilder via reflection) to accept non-finite values.
- Sanitize the producer to emit null or a sentinel instead of NaN/Infinity.
- Use a custom TypeAdapter<double> that maps null to NaN/0.
- Validate the document with a regex/token check for NaN|Infinity before parsing if you must reject rather than accept.
Example fix
// before
Gson gson = new Gson(); // default strictness rejects NaN
// after
Gson gson = new GsonBuilder()
.setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER)
.create();
JsonReader r = new JsonReader(reader);
r.setStrictness(Strictness.LENIENT); Defensive patterns
Strategy: validation
Validate before calling
if (reader.getStrictness() != Strictness.LENIENT && sourceContainsNonFinite(json)) {
reader.setStrictness(Strictness.LENIENT);
}
Type guard
boolean acceptsNonFinite(JsonReader r) {
return r.isLenient();
}
Try / catch
try {
return policy.readNumber(in);
} catch (MalformedJsonException ex) {
if (ex.getMessage().contains("NaN and infinities")) {
in.setStrictness(Strictness.LENIENT); // or return null
}
throw ex;
}
Prevention
- Set LENIENT strictness when ingesting JS-produced JSON.
- Sanitize producers to emit null instead of NaN/Infinity.
- Document strictness assumptions in API contracts.
When it happens
Trigger: JSON payload containing NaN, Infinity, -Infinity literals while the JsonReader strictness is not LENIENT; deserializing into double fields from non-spec-compliant producers (some JS encoders, older Java serializers).
Common situations: Interfacing with JavaScript JSON.stringify on non-finite numbers; legacy serializers that emit Infinity; strictness left at default (LEGACY_STRICT/STRICT).
Related errors
- Cannot parse {value}; at path {in.getPreviousPath()}
- Did not consume the entire document.
- cannot deserialize {baseType} because it does not define a f
- cannot deserialize {baseType} subtype named {label}; did you
- Type adapter '{typeAdapter}' returned wrong type; requested
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/a6ab40277494b4dd.json.
Report an issue: GitHub.