apache/flink · error · NumberFormatException
Invalid character.
Error message
Invalid character.
What it means
Thrown by IntParser.parseField when a byte inside the field is not an ASCII digit. The digit loop accepts only '0'..'9' (byte range 48-57) after an optional leading '-'; grouping separators, '+', '.', whitespace, or letters all trigger this NumberFormatException.
Source
Thrown at flink-core/src/main/java/org/apache/flink/types/parser/IntParser.java:146
if (bytes[startPos] == delimiter) {
throw new NumberFormatException("Empty field.");
}
if (bytes[startPos] == '-') {
neg = true;
startPos++;
length--;
if (length == 0 || bytes[startPos] == delimiter) {
throw new NumberFormatException("Orphaned minus sign.");
}
}
for (; length > 0; startPos++, length--) {
if (bytes[startPos] == delimiter) {
return (int) (neg ? -val : val);
}
if (bytes[startPos] < 48 || bytes[startPos] > 57) {
throw new NumberFormatException("Invalid character.");
}
val *= 10;
val += bytes[startPos] - 48;
if (val > OVERFLOW_BOUND && (!neg || val > UNDERFLOW_BOUND)) {
throw new NumberFormatException("Value overflow/underflow");
}
}
return (int) (neg ? -val : val);
}
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Produce plain unformatted integers for int columns (no separators, no plus sign, no exponent).
- If values may be formatted or fractional, parse via BigDecimal first, validate scale, then narrow.
- Route fields failing a non-digit pre-scan to a side output for reprocessing.
Example fix
// before
int v = IntParser.parseField(bytes, start, len, '|'); // fails on "1,000"
// after
String field = new String(bytes, start, len, StandardCharsets.UTF_8).replace(",", "");
int v = Integer.parseInt(field.trim()); Defensive patterns
Strategy: validation
Validate before calling
for (int i = 0; i < len; i++) {
byte b = bytes[start + i];
if (b == (byte) delimiter) break;
if (b < 48 || b > 57) throw new IllegalArgumentException("Non-digit byte in int field: " + (char) b);
} Try / catch
try {
int v = IntParser.parseField(bytes, start, len, delim);
} catch (NumberFormatException e) {
String raw = new String(bytes, start, len, StandardCharsets.UTF_8);
int v = Integer.parseInt(raw.replace(",", "").trim()); // fallback for formatted input
} Prevention
- Produce digit-only integers for int columns.
- Pre-scan for non-digit bytes when input format is not controlled.
- Divert malformed records to a dead-letter path instead of failing the job.
When it happens
Trigger: Calling IntParser.parseField with fields like "1,000", "+7", "12 ", "3.0", or "1e5" — any non-digit byte before the delimiter at IntParser.java:147.
Common situations: Locale-formatted numbers from spreadsheets/BI exports; decimal strings fed to an int column; hex or scientific notation; schema drift changing a column's content format.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/ab77ddcf4cb5713b.
Report an issue: GitHub.