{"record":{"id":"12e4fa02ac226862","repo":"apache/flink","slug":"seek-to-many-rows","errorCode":null,"errorMessage":"Seek to many rows.","messagePattern":"Seek to many rows\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/vector/ParquetColumnarRowSplitReader.java","lineNumber":365,"sourceCode":"\n        List<BlockMetaData> blockMetaData = reader.getRowGroups();\n\n        for (BlockMetaData metaData : blockMetaData) {\n            if (metaData.getRowCount() > rowCount) {\n                break;\n            } else {\n                reader.skipNextRowGroup();\n                rowsReturned += metaData.getRowCount();\n                totalCountLoadedSoFar += metaData.getRowCount();\n                rowsInBatch = (int) metaData.getRowCount();\n                nextRow = (int) metaData.getRowCount();\n                rowCount -= metaData.getRowCount();\n            }\n        }\n        for (int i = 0; i < rowCount; i++) {\n            boolean end = reachedEnd();\n            if (end) {\n                throw new RuntimeException(\"Seek to many rows.\");\n            }\n            nextRecord();\n        }\n    }\n\n    @Override\n    public void close() throws IOException {\n        if (reader != null) {\n            reader.close();\n            reader = null;\n        }\n    }\n\n    /** Interface to gen {@link VectorizedColumnBatch}. */\n    public interface ColumnBatchGenerator {\n        VectorizedColumnBatch generate(ColumnVector[] readVectors);\n    }\n}","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/vector/ParquetColumnarRowSplitReader.java#L347-L383","documentation":"RuntimeException from seekToRow(long) in ParquetColumnarRowSplitReader: after skipping whole row groups, the method loops rowCount times calling reachedEnd()/nextRecord(); if the file signals end-of-input before the seek completes, the requested offset exceeds the rows actually available. Like the 'expecting more rows' error, it usually indicates footer row counts larger than real data, or a seek offset beyond the split.","triggerScenarios":"seekToRow(rowCount) with rowCount larger than the rows remaining after skipped row groups - reachedEnd() returns true inside the seek loop and the RuntimeException fires.","commonSituations":"Split offsets computed from stale or wrong file metadata; corrupted/truncated Parquet files where actual rows < footer row count; concurrent file replacement between planning and reading.","solutions":["Recompute the split offsets from the same file version the reader opens (avoid TOCTOU between job planning and task execution)","Validate the file with parquet-tools; regenerate corrupted files","Clamp the seek offset to the row count reported by the reader's own footer before calling seekToRow"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"long available = reader.getTotalRowCount(); // totalRowCount from footer\nif (seekOffset >= available) { throw new IllegalArgumentException(\"seek offset \" + seekOffset + \" >= row count \" + available); }\nreader.seekToRow(seekOffset);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive split offsets and row counts from the same file snapshot used for reading","Clamp offsets to footer row counts before seeking"],"tags":["parquet","seek","metadata-mismatch","flink"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}