google/gson · error · IllegalArgumentException

Numeric values must be finite, but was {}

Error message

Numeric values must be finite, but was {}

What it means

Thrown by JsonWriter.value(float) (JsonWriter.java:578-582) when strictness != LENIENT and the float is NaN or Infinite. RFC 8259 forbids NaN and infinities in JSON, so in the default LEGACY_STRICT (or STRICT) mode the writer refuses to emit them. The message echoes the offending value.

Source

Thrown at gson/src/main/java/com/google/gson/stream/JsonWriter.java:581

    out.write(value ? "true" : "false");
    return this;
  }

  /**
   * Encodes {@code value}.
   *
   * @param value a finite value, or if {@link #setStrictness(Strictness) lenient}, also {@link
   *     Float#isNaN() NaN} or {@link Float#isInfinite() infinity}.
   * @return this writer.
   * @throws IllegalArgumentException if the value is NaN or Infinity and this writer is not {@link
   *     #setStrictness(Strictness) lenient}.
   * @since 2.9.1
   */
  @CanIgnoreReturnValue
  public JsonWriter value(float value) throws IOException {
    writeDeferredName();
    if (strictness != Strictness.LENIENT && (Float.isNaN(value) || Float.isInfinite(value))) {
      throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
    }
    beforeValue();
    out.append(Float.toString(value));
    return this;
  }

  /**
   * Encodes {@code value}.
   *
   * @param value a finite value, or if {@link #setStrictness(Strictness) lenient}, also {@link
   *     Double#isNaN() NaN} or {@link Double#isInfinite() infinity}.
   * @return this writer.
   * @throws IllegalArgumentException if the value is NaN or Infinity and this writer is not {@link
   *     #setStrictness(Strictness) lenient}.
   */
  @CanIgnoreReturnValue
  public JsonWriter value(double value) throws IOException {
    writeDeferredName();

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Guard the value: if (Float.isFinite(v)) writer.value(v) else writer.nullValue() (or omit the field).
  2. If you genuinely need to emit NaN/Infinity, set writer.setStrictness(Strictness.LENIENT).
  3. Sanitize inputs upstream so NaN/Infinity never reaches the writer.
  4. Log when a value is coalesced to null for diagnostics.

Example fix

// before
writer.value(ratio); // throws when ratio is NaN

// after
if (Float.isFinite(ratio)) {
  writer.value(ratio);
} else {
  writer.nullValue();
}
Defensive patterns

Strategy: validation

Validate before calling

if (Float.isFinite(v)) {
  writer.value(v);
} else {
  writer.nullValue(); // or omit the field entirely
}

Type guard

static boolean isEmittableFloat(float v) {
  return Float.isFinite(v);
}

Try / catch

try {
  writer.value(v);
} catch (IllegalArgumentException e) {
  writer.nullValue();
}

Prevention

When it happens

Trigger: Calling writer.value(Float.NaN) or writer.value(Float.POSITIVE_INFINITY) without enabling lenient mode; computations that produce NaN/Infinity (division by zero, undefined math) being written directly.

Common situations: Aggregations or statistical fields that can be NaN when no data exists; floating-point division without guards; migrating data that previously tolerated special values; serializers that pass floats straight through.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/3b5cb5b8638bcda7. Report an issue: GitHub.