google/gson · error · IllegalArgumentException

JSON forbids NaN and infinities: {value}

Error message

JSON forbids NaN and infinities: {value}

What it means

Thrown by JsonTreeWriter.value(float) when the writer is not in lenient mode and the supplied float is NaN or infinite. JSON has no representation for these values (the grammar only permits finite numbers), so Gson refuses to emit them by default. The check uses Float.isNaN / Float.isInfinite and the original value appears in the message.

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/JsonTreeWriter.java:191

    put(new JsonPrimitive(value));
    return this;
  }

  @CanIgnoreReturnValue
  @Override
  public JsonWriter value(Boolean value) throws IOException {
    if (value == null) {
      return nullValue();
    }
    put(new JsonPrimitive(value));
    return this;
  }

  @CanIgnoreReturnValue
  @Override
  public JsonWriter value(float value) throws IOException {
    if (!isLenient() && (Float.isNaN(value) || Float.isInfinite(value))) {
      throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
    }
    put(new JsonPrimitive(value));
    return this;
  }

  @CanIgnoreReturnValue
  @Override
  public JsonWriter value(double value) throws IOException {
    if (!isLenient() && (Double.isNaN(value) || Double.isInfinite(value))) {
      throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
    }
    put(new JsonPrimitive(value));
    return this;
  }

  @CanIgnoreReturnValue
  @Override
  public JsonWriter value(long value) throws IOException {

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Sanitize the float before serialization: replace NaN/Infinity with null (and serialize nulls off) or with a sentinel finite value.
  2. Enable lenient mode on the writer (setLenient(true)) if the downstream consumer accepts NaN/Infinity tokens (non-standard JSON).
  3. Register a custom TypeAdapter<Float> that converts NaN/Infinity to null or 0.
  4. Fix the upstream computation so it never produces NaN/Infinity for fields that will be serialized.

Example fix

// before
float v = 0.0f / 0.0f; // NaN
new Gson().toJson(v); // throws IllegalArgumentException

// after: sanitize, or use lenient
float safe = Float.isNaN(v) || Float.isInfinite(v) ? 0f : v;
new Gson().toJson(safe);
// or:
JsonWriter w = ...; w.setLenient(true); w.value(v);
Defensive patterns

Strategy: validation

Validate before calling

// Sanitize float before serialization
float safe = (Float.isNaN(v) || Float.isInfinite(v)) ? 0f : v;
out.value(safe);

Try / catch

try {
  out.value(v);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("JSON forbids NaN")) {
    out.value(0f); // or out.nullValue()
  } else throw e;
}

Prevention

When it happens

Trigger: Calling value(float) with Float.NaN, Float.POSITIVE_INFINITY, or Float.NEGATIVE_INFINITY while isLenient()==false (the Gson default). Common when a float field of a serialized object holds NaN from a division (0.0f/0.0f) or an unbounded computation.

Common situations: Serializing sensor/scientific data where NaN marks missing readings; graphics code that lets infinity leak into fields; math results not sanitized before serialization; tests that feed edge-case floats through Gson without lenient mode.

Related errors


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