google/gson · error · NumberFormatException
Number has unsupported scale
Error message
Number has unsupported scale: ${s} What it means
NumberLimits rejects any BigDecimal whose scale's absolute value is >= 10,000 (NumberLimits.java:26). Extremely large scales cause pathological memory/CPU usage in BigDecimal arithmetic; Gson treats them as malformed.
Solutions
- Constrain accepted numeric precision at the schema/validation boundary (e.g. max significant digits).
- If you need wide ranges, accept the value as a quoted String and parse with a bounded custom parser rather than BigDecimal.
- Cap JSON request size and field length so pathological numbers cannot reach NumberLimits.
Example fix
// before
BigDecimal v = NumberLimits.parseBigDecimal(input);
// after
BigDecimal test = new BigDecimal(input);
if (Math.abs(test.scale()) >= 10_000) throw new IllegalArgumentException("scale too large");
// (or simply let NumberLimits throw and handle the NumberFormatException at the boundary) Defensive patterns
Strategy: validation
Validate before calling
BigDecimal probe = new BigDecimal(s);
if (Math.abs(probe.scale()) >= 10_000) throw new NumberFormatException("scale too large");
BigDecimal v = NumberLimits.parseBigDecimal(s); Type guard
static boolean scaleOK(String s) { try { return Math.abs(new BigDecimal(s).scale()) < 10_000; } catch (Exception e) { return false; } } Try / catch
try { NumberLimits.parseBigDecimal(s); } catch (NumberFormatException e) { /* unsupported scale or malformed */ } Prevention
- Validate numeric precision/significant digits in your schema.
- For very-wide-range numbers, accept a quoted String and parse with a bounded custom parser.
- Treat scale-related NumberFormatException as adversarial input at the boundary.
When it happens
Trigger: Parsing a JSON number whose scale magnitude is >= 10,000, e.g. extremely high-precision decimals like 1e-50000 or 0.000... (10k+ zeros) ...1, via NumberLimits.parseBigDecimal / LazilyParsedNumber.asBigDecimal / big-decimal coercion.
Common situations: Untrusted numeric input engineered to exhaust memory; scientific/engineering payloads with absurd precision; malformed fixed-point fields; adversarial JSON fuzzing.
Related errors
- Number string too large
- Failed parsing JSON source
- Did not consume the entire document.
- End of input
- Expected a long but was
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/e2118e6f14245733.
Report an issue: GitHub.
Appendix: source
Thrown at gson/src/main/java/com/google/gson/internal/NumberLimits.java:27
*/
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)