google/gson · error · NumberFormatException
Number string too large: ${s.substring(0, 30)}...
Error message
Number string too large: ${s.substring(0, 30)}... What it means
NumberLimits enforces a 10,000-character cap on number strings parsed from JSON to prevent algorithmic-complexity attacks (BigDecimal/BigInteger parsing is superlinear). Strings exceeding MAX_NUMBER_STRING_LENGTH throw NumberFormatException with a 30-char preview (NumberLimits.java:16).
Source
Thrown at gson/src/main/java/com/google/gson/internal/NumberLimits.java:17
package com.google.gson.internal;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* This class enforces limits on numbers parsed from JSON to avoid potential performance problems
* when extremely large numbers are used.
*/
public final class NumberLimits {
private NumberLimits() {}
private static final int MAX_NUMBER_STRING_LENGTH = 10_000;
private static void checkNumberStringLength(String s) {
if (s.length() > MAX_NUMBER_STRING_LENGTH) {
throw new NumberFormatException("Number string too large: " + s.substring(0, 30) + "...");
}
}
public static BigDecimal parseBigDecimal(String s) throws NumberFormatException {
checkNumberStringLength(s);
BigDecimal decimal = new BigDecimal(s);
// Cast to long to avoid issues with abs when value is Integer.MIN_VALUE
if (Math.abs((long) decimal.scale()) >= 10_000) {
throw new NumberFormatException("Number has unsupported scale: " + s);
}
return decimal;
}
public static BigInteger parseBigInteger(String s) throws NumberFormatException {
checkNumberStringLength(s);
return new BigInteger(s);
}View on GitHub (pinned to 310ac341f2)
Solutions
- Validate input length before parsing and reject/truncate at the trust boundary.
- If you genuinely need huge numbers, pre-process the JSON to express them as quoted strings and parse with an explicit, bounded parser.
- Cap request body size upstream so such payloads never reach the parser.
Example fix
// before
BigDecimal v = NumberLimits.parseBigDecimal(hugeNumberString);
// after
if (hugeNumberString.length() > 10_000) throw new IllegalArgumentException("number too large");
BigDecimal v = NumberLimits.parseBigDecimal(hugeNumberString); Defensive patterns
Strategy: validation
Validate before calling
private static final int MAX = 10_000;
if (s != null && s.length() > MAX) throw new NumberFormatException("number string too large");
BigDecimal d = NumberLimits.parseBigDecimal(s); Type guard
static boolean withinLength(String s) { return s != null && s.length() <= 10_000; } Try / catch
try { NumberLimits.parseBigDecimal(s); } catch (NumberFormatException e) { /* too large or malformed */ } Prevention
- Cap incoming JSON/request body size at the trust boundary.
- Reject or coerce to String any numeric field whose source length can exceed 10k chars.
- Treat NumberFormatException from numeric coercion as a malformed-input signal, not a crash.
When it happens
Trigger: Calling NumberLimits.parseBigDecimal or parseBigInteger (or Gson paths that funnel through them, e.g. LazilyParsedNumber.asBigDecimal / big-decimal coercion) on a JSON number with more than 10,000 characters.
Common situations: Processing untrusted JSON containing adversarial huge numbers; binary blobs encoded as numeric strings; misformatted scientific-notation fields with absurd exponents; accidental concatenation producing very long numeric strings.
Related errors
- Number has unsupported scale: ${s}
- Failed parsing JSON source: ${reader} to Json
- Did not consume the entire document.
- Failed invoking canAccess
- Failed parsing '${s}' as BigInteger; at path ${path}
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/5551e757e034dc59.
Report an issue: GitHub.