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

  1. Produce plain unformatted integers for int columns (no separators, no plus sign, no exponent).
  2. If values may be formatted or fractional, parse via BigDecimal first, validate scale, then narrow.
  3. 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

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

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/ab77ddcf4cb5713b. Report an issue: GitHub.