{"record":{"id":"62d78dd64a3f5644","repo":"apache/flink","slug":"row-too-short","errorCode":null,"errorMessage":"Row too short: {}","messagePattern":"Row too short: (.+?)","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/io/GenericCsvInputFormat.java","lineNumber":390,"sourceCode":"        super.close();\n    }\n\n    protected boolean parseRecord(Object[] holders, byte[] bytes, int offset, int numBytes)\n            throws ParseException {\n\n        boolean[] fieldIncluded = this.fieldIncluded;\n\n        int startPos = offset;\n        final int limit = offset + numBytes;\n\n        for (int field = 0, output = 0; field < fieldIncluded.length; field++) {\n\n            // check valid start position\n            if (startPos > limit || (startPos == limit && field != fieldIncluded.length - 1)) {\n                if (lenient) {\n                    return false;\n                } else {\n                    throw new ParseException(\n                            \"Row too short: \" + new String(bytes, offset, numBytes, getCharset()));\n                }\n            }\n\n            if (fieldIncluded[field]) {\n                // parse field\n                @SuppressWarnings(\"unchecked\")\n                FieldParser<Object> parser = (FieldParser<Object>) this.fieldParsers[output];\n                Object reuse = holders[output];\n                startPos =\n                        parser.resetErrorStateAndParse(\n                                bytes, startPos, limit, this.fieldDelim, reuse);\n                holders[output] = parser.getLastResult();\n\n                // check parse result\n                if (startPos < 0) {\n                    // no good\n                    if (lenient) {","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/io/GenericCsvInputFormat.java#L372-L408","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove empty/blank lines from the input file, or filter them upstream.","Enable lenient mode on the format (format.setLenient(true)) so malformed/short rows are skipped instead of aborting.","Verify fieldDelimiter and lineDelimiter (including quotedStringParsing / quoteCharacter) match how the file was written.","Reduce the number of configured field types to match the actual column count, or pad the source rows."],"exampleFix":"// before\nformat.setLenient(false); // default, throws on blank rows\n// after\nformat.setLenient(true); // skips rows that are too short","handlingStrategy":"validation","validationCode":"// Decide policy before opening the format based on whether the file may have blank rows\nboolean fileMayContainBlankRows = ...; // inspect a sample\nformat.setLenient(!fileMayContainBlankRows);\n// or validate a sample line length matches the configured arity\nint expected = numConfiguredFields;\ntry (BufferedReader br = new BufferedReader(new FileReader(samplePath))) {\n    String line;\n    while ((line = br.readLine()) != null) {\n        if (line.isEmpty() || countFields(line, delim) < expected) {\n            format.setLenient(true); break;\n        }\n    }\n}","typeGuard":"// Guard row acceptance downstream if you must stay strict\nDataStream<Row> strict = source.filter(r -> r != null && r.getArity() == expectedArity);","tryCatchPattern":"try {\n    return format.nextRecord(reuse);\n} catch (ParseException e) {\n    if (e.getMessage().startsWith(\"Row too short\")) {\n        // optionally log and continue, or enable lenient and re-read\n        return null; // skip row\n    }\n    throw e;\n}","preventionTips":["Strip blank/short lines from the input before the job, or pre-validate a sample for arity.","Default to setLenient(true) when the file format is not fully under your control.","Double-check fieldDelimiter and lineDelimiter against the actual file bytes (CRLF vs LF)."],"tags":["csv","input-format","data-quality","parsing"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}