google/gson · error · JsonSyntaxException
Failed parsing '${s}' as BigInteger; at path ${path}
Error message
Failed parsing '${s}' as BigInteger; at path ${path} What it means
Thrown by Gson's built-in BigInteger TypeAdapter when the JSON value cannot be parsed by NumberLimits.parseBigInteger. Gson reads the token as a string (so it accepts both JSON numbers and JSON strings) and delegates to BigInteger parsing; if the text contains non-numeric characters, exponents in unsupported form, or is empty, a NumberFormatException is wrapped as a JsonSyntaxException pinpointing the offending path.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java:619
}
};
public static final TypeAdapterFactory BIG_DECIMAL_FACTORY =
newFactory(BigDecimal.class, BIG_DECIMAL);
public static final TypeAdapter<BigInteger> BIG_INTEGER =
new TypeAdapter<BigInteger>() {
@Override
public BigInteger read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String s = in.nextString();
try {
return NumberLimits.parseBigInteger(s);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(
"Failed parsing '" + s + "' as BigInteger; at path " + in.getPreviousPath(), e);
}
}
@Override
public void write(JsonWriter out, BigInteger value) throws IOException {
out.value(value);
}
};
public static final TypeAdapterFactory BIG_INTEGER_FACTORY =
newFactory(BigInteger.class, BIG_INTEGER);
public static final TypeAdapter<LazilyParsedNumber> LAZILY_PARSED_NUMBER =
new TypeAdapter<LazilyParsedNumber>() {
// Normally users should not be able to access and deserialize LazilyParsedNumber because
// it is an internal type, but implement this nonetheless in case there are legit corner
// cases where this is possibleView on GitHub (pinned to 310ac341f2)
Solutions
- Inspect the 'at path' location in the error and fix the source JSON so the value is an integer string like "123" or a JSON integer number.
- If the value legitimately may contain decimals/commas, change the Java field to BigDecimal or String and convert manually.
- Register a custom TypeAdapter<BigInteger> that strips thousands separators or rounds decimals before calling new BigInteger(cleaned).
- Sanitize input at the API boundary before handing the JSON to Gson.
Example fix
// before
public class Account { public BigInteger balanceMicros; }
// JSON: {"balanceMicros":"1,000.00"} -> fails
// after: use BigDecimal or sanitize
public class Account {
public String balanceMicros; // or BigDecimal
public BigInteger asBigInteger() { return new BigInteger(balanceMicros.replaceAll("[^0-9-]","")); }
}
// or custom adapter:
Gson g = new GsonBuilder()
.registerTypeHierarchyAdapter(BigInteger.class, new TypeAdapter<BigInteger>() {
public BigInteger read(JsonReader in) throws IOException {
String s = in.nextString().replaceAll("[,]","");
return new BigInteger(s);
}
public void write(JsonWriter out, BigInteger v) throws IOException { out.value(v); }
}).create(); Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern BIG_INT = Pattern.compile("[+-]?\\d+");
String raw = jsonNode.get("balanceMicros").getAsString();
if (!BIG_INT.matcher(raw.trim()).matches()) {
throw new IllegalArgumentException("Not a BigInteger: " + raw);
}
// now safe to call fromJson or new BigInteger(raw.trim()) Try / catch
try {
return gson.fromJson(json, HasBigInt.class);
} catch (JsonSyntaxException e) {
if (e.getMessage().contains("as BigInteger")) {
// log offending path, default, or reject the record
throw new IllegalArgumentException("Invalid BigInteger in payload", e);
}
throw e;
} Prevention
- Validate numeric strings with a [+-]?\\d+ regex before deserialization.
- Prefer BigDecimal for monetary/decimal payloads to avoid integer-only rejection.
- Run contract tests with malformed numbers to ensure the error surfaces clearly.
- Sanitize thousands separators/whitespace at the API boundary, not inside Gson.
When it happens
Trigger: Deserializing JSON into a field/element of type java.math.BigInteger (or Map<BigInteger, ...>) where the JSON value is non-numeric (e.g. "abc", "", "NaN", "1.5" with fractional part that BigInteger rejects, or an object/array token that the reader coerced). Also triggered when a JSON number has a floating exponent/sign that BigInteger cannot represent.
Common situations: Sending a decimal/floating value like 3.14 into a BigInteger field; receiving IDs from an upstream service that quotes numbers as strings with stray characters; locale-specific formatting (commas as thousands separators e.g. "1,000"); mistakenly mapping a BigInteger field onto a JSON object.
Related errors
- Failed parsing '${s}' as UUID; at path ${path}
- Failed parsing '${s}' as Currency; at path ${path}
- Failed parsing '${s}' as InetAddress; at path ${path}; to al
- Did not consume the entire document.
- Failed parsing JSON source: ${reader} to Json
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/7cd05ed68288e907.
Report an issue: GitHub.