apache/flink · error · NumberFormatException
Invalid character.
Error message
Invalid character.
What it means
Thrown by ByteParser.parseField during the digit loop when a byte inside the numeric field is outside '0'..'9'. The parser is strict: no thousands separators, no '+', no decimal point, no whitespace — only ASCII digits (checked via byte range 48-57) after an optional leading '-' are accepted for byte fields.
Source
Thrown at flink-core/src/main/java/org/apache/flink/types/parser/ByteParser.java:138
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 (byte) (neg ? -val : val);
}
if (bytes[startPos] < 48 || bytes[startPos] > 57) {
throw new NumberFormatException("Invalid character.");
}
val *= 10;
val += bytes[startPos] - 48;
if (val > Byte.MAX_VALUE && (!neg || val > -Byte.MIN_VALUE)) {
throw new NumberFormatException("Value overflow/underflow");
}
}
return (byte) (neg ? -val : val);
}
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Emit plain unformatted integers (no separators, no plus sign) for byte columns at the producer.
- If the value may be fractional or formatted, parse it as double/BigDecimal first and range-check before narrowing to byte.
- Pre-scan the field for non-digit bytes and route bad records to a dead-letter/side output.
Example fix
// before
byte v = ByteParser.parseField(bytes, start, len, '|'); // fails on "1,000"
// after
String field = new String(bytes, start, len, StandardCharsets.UTF_8).replace(",", "");
byte v = Byte.valueOf(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 byte field: " + (char) b);
} Try / catch
try {
byte v = ByteParser.parseField(bytes, start, len, delim);
} catch (NumberFormatException e) {
String raw = new String(bytes, start, len, StandardCharsets.UTF_8);
byte v = Byte.parseByte(raw.replace(",", "").trim()); // fallback for formatted input
} Prevention
- Emit unformatted integers (no separators, '+', or '.') for byte columns.
- Pre-validate fields are digit-only before strict parsing.
- Route non-conforming records to a reprocessing path instead of crashing the pipeline.
When it happens
Trigger: Calling ByteParser.parseField with fields like "1,000", "12 ", "0x1F", "+5", or "3.0" — any non-digit byte before the delimiter triggers the rejection at ByteParser.java:140.
Common situations: Locale-formatted numbers with grouping separators from spreadsheets; float values fed into a byte/int column; hex or signed-plus notation; schema drift where a byte column starts receiving formatted strings.
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/8a686b647bd8e506.
Report an issue: GitHub.