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
- Guard the value: if (Float.isFinite(v)) writer.value(v) else writer.nullValue() (or omit the field).
- If you genuinely need to emit NaN/Infinity, set writer.setStrictness(Strictness.LENIENT).
- Sanitize inputs upstream so NaN/Infinity never reaches the writer.
- 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
- Guard all float outputs with Float.isFinite before writing.
- Sanitize computations that can yield NaN/Infinity (averages, ratios).
- Enable Strictness.LENIENT only if non-finite emission is intentional.
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
- String created by {} is not a valid JSON number: {}
- {} requires {} type arguments, but got {}
- Invalid nesting limit: {}
- Expected a long but was {}{}
- Expected an int but was {}{}
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/3b5cb5b8638bcda7.
Report an issue: GitHub.