google/gson · error · NumberFormatException
Invalid number: {}
Error message
Invalid number: {} What it means
Thrown by ISO8601Utils.parseInt when the FIRST character of a date/time numeric field is not a decimal digit (Character.digit returns < 0). parseInt parses substrings for year/month/day/hour/minute/second/fraction; a non-digit at the very first position triggers NumberFormatException("Invalid number: <substring>"), which ISO8601Utils rewraps as a ParseException.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java:344
* @param value the string to parse
* @param beginIndex the start index for the integer in the string
* @param endIndex the end index for the integer in the string
* @return the int
* @throws NumberFormatException if the value is not a number
*/
private static int parseInt(String value, int beginIndex, int endIndex)
throws NumberFormatException {
if (beginIndex < 0 || endIndex > value.length() || beginIndex > endIndex) {
throw new NumberFormatException(value);
}
// use same logic as in Integer.parseInt() but less generic we're not supporting negative values
int i = beginIndex;
int result = 0;
int digit;
if (i < endIndex) {
digit = Character.digit(value.charAt(i++), 10);
if (digit < 0) {
throw new NumberFormatException("Invalid number: " + value.substring(beginIndex, endIndex));
}
result = -digit;
}
while (i < endIndex) {
digit = Character.digit(value.charAt(i++), 10);
if (digit < 0) {
throw new NumberFormatException("Invalid number: " + value.substring(beginIndex, endIndex));
}
result *= 10;
result -= digit;
}
return -result;
}
/**
* Zero pad a number to a specified length
*
* @param buffer buffer to use for paddingView on GitHub (pinned to 310ac341f2)
Solutions
- Validate the date string against an ISO8601 regex before parsing (e.g. ^\d{4}-\d{2}-\d{2}T...).
- Fix the producer to emit well-formed ISO8601 with zero-padded numeric components.
- Register a custom TypeAdapter<Date> tolerant to the actual format you receive.
- Sanitize input (replace alternate separators, trim whitespace) before Gson.
Example fix
// before
// JSON: {"at":"2020-0a-01T00:00:00Z"} -> 'Invalid number: 0a'
// after: validate at boundary
String s = jsonValue;
if (!s.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2})")) {
throw new IllegalArgumentException("not ISO8601: " + s);
}
Date d = gson.fromJson(json, MyType.class).at; Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern ISO =
Pattern.compile("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$");
String raw = jsonNode.get("at").getAsString();
if (raw == null || !ISO.matcher(raw).matches()) {
throw new IllegalArgumentException("Malformed ISO8601 date (non-digit component): " + raw);
} Try / catch
try {
return gson.fromJson(json, Event.class);
} catch (JsonSyntaxException e) {
if (e.getCause() instanceof ParseException && e.getCause().getMessage().contains("Invalid number")) {
throw new IllegalArgumentException("Corrupt date field", e);
}
throw e;
} Prevention
- Validate ISO8601 with a strict regex before parsing.
- Ensure producers zero-pad all numeric components (month, day, hour, minute, second).
- Run fuzz/property tests with random character substitutions to ensure clean rejection.
- Normalize separators and trim whitespace at ingestion.
When it happens
Trigger: A date component that should be numeric contains a non-digit at its start: e.g. month value starting with a letter, a separator character where a digit is expected, or an off-by-one parse where the position lands on a delimiter. Example: "2020-0a-01" or a malformed date where offsets into the string are wrong.
Common situations: Truncated date strings (too short, so offset walks into next field's delimiter); corrupted log timestamps; locale-specific separators ('/' instead of '-'); producers that left-pad with spaces instead of zeros; encoding issues inserting non-ASCII digits.
Related errors
- No time zone indicator
- Mismatching time zone indicator: {} given, resolves to {}
- Invalid time zone indicator '{}'
- Failed parsing '{}' as SQL Date; at path {}
- Failed parsing '{}' as SQL Time; at path {}
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/db4f044caaae093c.
Report an issue: GitHub.