apache/flink · error · NumberFormatException
Invalid character.
Error message
Invalid character.
What it means
Thrown by LongParser.parseField when a byte inside the field is not an ASCII digit. The digit loop accepts only '0'..'9' after an optional leading '-'; separators, '+', '.', whitespace, or letters trigger this NumberFormatException before any overflow checking.
Source
Thrown at flink-core/src/main/java/org/apache/flink/types/parser/LongParser.java:154
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 neg ? -val : val;
}
if (bytes[startPos] < 48 || bytes[startPos] > 57) {
throw new NumberFormatException("Invalid character.");
}
val *= 10;
val += bytes[startPos] - 48;
// check for overflow / underflow
if (val < 0) {
// this is an overflow/underflow, unless we hit exactly the Long.MIN_VALUE
if (neg && val == Long.MIN_VALUE) {
if (length == 1 || bytes[startPos + 1] == delimiter) {
return Long.MIN_VALUE;
} else {
throw new NumberFormatException("value overflow");
}
} else {
throw new NumberFormatException("value overflow");
}
}
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Emit plain digit-only integers for long columns at the producer.
- Parse formatted/fractional input via BigDecimal first, validate, then convert to long.
- Pre-scan fields for non-digit bytes and divert bad records to a dead-letter path.
Example fix
// before
long v = LongParser.parseField(bytes, start, len, '|'); // fails on "1,000,000"
// after
String field = new String(bytes, start, len, StandardCharsets.UTF_8).replace(",", "");
long v = Long.parseLong(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 long field: " + (char) b);
} Try / catch
try {
long v = LongParser.parseField(bytes, start, len, delim);
} catch (NumberFormatException e) {
String raw = new String(bytes, start, len, StandardCharsets.UTF_8);
long v = Long.parseLong(raw.replace(",", "").trim()); // fallback for formatted input
} Prevention
- Emit digit-only integers for long columns.
- Pre-validate non-digit bytes for untrusted input.
- Send malformed records to a reprocessing path rather than crashing.
When it happens
Trigger: Calling LongParser.parseField with fields like "1,000,000", "+9", "123 ", or "9.5" — any non-digit byte before the delimiter at LongParser.java:155.
Common situations: Grouping separators in spreadsheet/BI exports; decimal or scientific values in a long column; stray padding; schema drift changing column formats.
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/fddbc4a75259f9e8.
Report an issue: GitHub.