apache/flink · error · NumberFormatException

Empty field.

Error message

Empty field.

What it means

Thrown by ByteParser.parseField(byte[], int, int, char) when the first byte of the field equals the delimiter, meaning the column is empty. The parser scans bytes directly and treats a delimiter at the start position as an empty field, rejecting it with NumberFormatException before any digit processing.

Solutions

  1. Fix the input data or delimiter config so byte columns are non-empty.
  2. Guard at the call site: if bytes[startPos] == delimiter, substitute a default or skip the record.
  3. If empty cells are valid in your format, define an explicit mapping (empty -> 0/null) instead of parsing.

Example fix

// before
byte v = ByteParser.parseField(bytes, start, len, '|');

// after
byte v = (len > 0 && bytes[start] == (byte) '|')
    ? 0
    : ByteParser.parseField(bytes, start, len, '|');
Defensive patterns

Strategy: validation

Validate before calling

if (len <= 0 || bytes[start] == (byte) delimiter) {
    // empty column: default or explicit error
    return 0;
}

Try / catch

try {
    byte v = ByteParser.parseField(bytes, start, len, delim);
} catch (NumberFormatException e) {
    // empty or malformed field: emit to side output with row context
}

Prevention

When it happens

Trigger: Calling ByteParser.parseField(bytes, startPos, length, delimiter) where bytes[startPos] == (byte) delimiter — e.g. input "a||c" parsed with '|' delimiter hitting an empty middle column.

Common situations: CSV with consecutive delimiters (empty numeric cell), trailing delimiter on a line producing an empty last field, or a column-count mismatch after a schema change drops a column.

Related errors


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

Appendix: source

Thrown at flink-core/src/main/java/org/apache/flink/types/parser/ByteParser.java:121

    /**
     * Static utility to parse a field of type byte from a byte sequence that represents text
     * characters (such as when read from a file stream).
     *
     * @param bytes The bytes containing the text data that should be parsed.
     * @param startPos The offset to start the parsing.
     * @param length The length of the byte sequence (counting from the offset).
     * @param delimiter The delimiter that terminates the field.
     * @return The parsed value.
     * @throws NumberFormatException Thrown when the value cannot be parsed because the text
     *     represents not a correct number.
     */
    public static final byte parseField(byte[] bytes, int startPos, int length, char delimiter) {
        long val = 0;
        boolean neg = false;

        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.");
            }

View on GitHub (pinned to 2f3c205e92)