apache/flink · error · ParseException

Row too short: {}

Error message

Row too short: {}

What it means

Thrown while parsing the FIRST field of a CSV row when the read cursor (startPos) is already past the row's byte limit, i.e. the record has no content / fewer bytes than the schema expects. Only thrown in non-lenient mode; in lenient mode the same condition returns false (the row is skipped). This guards rows that are empty or truncated before any field could be read.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/io/GenericCsvInputFormat.java:390

        super.close();
    }

    protected boolean parseRecord(Object[] holders, byte[] bytes, int offset, int numBytes)
            throws ParseException {

        boolean[] fieldIncluded = this.fieldIncluded;

        int startPos = offset;
        final int limit = offset + numBytes;

        for (int field = 0, output = 0; field < fieldIncluded.length; field++) {

            // check valid start position
            if (startPos > limit || (startPos == limit && field != fieldIncluded.length - 1)) {
                if (lenient) {
                    return false;
                } else {
                    throw new ParseException(
                            "Row too short: " + new String(bytes, offset, numBytes, getCharset()));
                }
            }

            if (fieldIncluded[field]) {
                // parse field
                @SuppressWarnings("unchecked")
                FieldParser<Object> parser = (FieldParser<Object>) this.fieldParsers[output];
                Object reuse = holders[output];
                startPos =
                        parser.resetErrorStateAndParse(
                                bytes, startPos, limit, this.fieldDelim, reuse);
                holders[output] = parser.getLastResult();

                // check parse result
                if (startPos < 0) {
                    // no good
                    if (lenient) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Remove empty/blank lines from the input file, or filter them upstream.
  2. Enable lenient mode on the format (format.setLenient(true)) so malformed/short rows are skipped instead of aborting.
  3. Verify fieldDelimiter and lineDelimiter (including quotedStringParsing / quoteCharacter) match how the file was written.
  4. Reduce the number of configured field types to match the actual column count, or pad the source rows.

Example fix

// before
format.setLenient(false); // default, throws on blank rows
// after
format.setLenient(true); // skips rows that are too short
Defensive patterns

Strategy: validation

Validate before calling

// Decide policy before opening the format based on whether the file may have blank rows
boolean fileMayContainBlankRows = ...; // inspect a sample
format.setLenient(!fileMayContainBlankRows);
// or validate a sample line length matches the configured arity
int expected = numConfiguredFields;
try (BufferedReader br = new BufferedReader(new FileReader(samplePath))) {
    String line;
    while ((line = br.readLine()) != null) {
        if (line.isEmpty() || countFields(line, delim) < expected) {
            format.setLenient(true); break;
        }
    }
}

Type guard

// Guard row acceptance downstream if you must stay strict
DataStream<Row> strict = source.filter(r -> r != null && r.getArity() == expectedArity);

Try / catch

try {
    return format.nextRecord(reuse);
} catch (ParseException e) {
    if (e.getMessage().startsWith("Row too short")) {
        // optionally log and continue, or enable lenient and re-read
        return null; // skip row
    }
    throw e;
}

Prevention

When it happens

Trigger: GenericCsvInputFormat is configured with N field types but a row in the file is empty, blank, or a single short token; the parser is in strict (non-lenient) mode (the default). The condition startPos > limit, or startPos == limit when there are still included fields to read, trips the check.

Common situations: CSV file with a trailing blank line; CRLF vs LF mismatch causing empty records; fieldDelimiter/lineDelimiter misconfigured so a whole line is consumed as one field; quoted-string parsing config consuming too much; reading a file written by a different tool that emits blank separator rows.

Related errors


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