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

  1. Set reader.setStrictness(Strictness.LENIENT) (or GsonBuilder via reflection) to accept non-finite values.
  2. Sanitize the producer to emit null or a sentinel instead of NaN/Infinity.
  3. Use a custom TypeAdapter<double> that maps null to NaN/0.
  4. 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

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


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/a6ab40277494b4dd.json. Report an issue: GitHub.