{"record":{"id":"4b5da3dda18ee309","repo":"prestodb/presto","slug":"reading-rle-byte-got-eof","errorCode":null,"errorMessage":"Reading RLE byte got EOF","messagePattern":"Reading RLE byte got EOF","errorType":"exception","errorClass":"OrcCorruptionException","httpStatus":null,"severity":"error","filePath":"presto-orc/src/main/java/com/facebook/presto/orc/stream/ByteInputStream.java","lineNumber":61,"sourceCode":"            throws IOException\n    {\n        lastReadInputCheckpoint = input.getCheckpoint();\n\n        int control = input.read();\n        if (control == -1) {\n            throw new OrcCorruptionException(input.getOrcDataSourceId(), \"Read past end of buffer RLE byte\");\n        }\n\n        offset = 0;\n\n        // if byte high bit is not set, this is a repetition; otherwise it is a literal sequence\n        if ((control & 0x80) == 0) {\n            length = control + MIN_REPEAT_SIZE;\n\n            // read the repeated value\n            int value = input.read();\n            if (value == -1) {\n                throw new OrcCorruptionException(input.getOrcDataSourceId(), \"Reading RLE byte got EOF\");\n            }\n\n            // fill buffer with the value\n            Arrays.fill(buffer, 0, length, (byte) value);\n        }\n        else {\n            // length is 2's complement of byte\n            length = 0x100 - control;\n\n            // read the literals into the buffer\n            input.readFully(buffer, 0, length);\n        }\n    }\n\n    @Override\n    public Class<ByteStreamCheckpoint> getCheckpointType()\n    {\n        return ByteStreamCheckpoint.class;","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-orc/src/main/java/com/facebook/presto/orc/stream/ByteInputStream.java#L43-L79","documentation":"Thrown by ByteInputStream.readNextBlock after a valid RLE run-control byte was read but the repeated value byte itself hit EOF (-1). The RLE header promised a run of control+MIN_REPEAT_SIZE bytes, yet the single value byte is missing, so the stream is malformed or truncated mid-run.","triggerScenarios":"ByteInputStream.next/skip triggers readNextBlock; control byte reads fine (high bit clear, i.e. repeat mode), but the immediately following input.read() returns -1 because the stream ends between the control byte and the value byte.","commonSituations":"Truncated ORC files (cut exactly inside an RLE run); interrupted file copies; corrupted network blocks stored without checksums; reading a snapshot of an in-progress ORC write.","solutions":["Confirm truncation with orc-tools meta/orc-dump and compare the declared stream length with the actual byte length.","Re-copy the file from a good source and verify checksums before querying again.","Re-write the file from source data with the current Presto/Hive writer.","Enable storage checksums (HDFS CRC, S3 ETag) so corruption is surfaced where it occurred.","Avoid querying tables while a transactional writer (insert into the same table) is still running."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    stream.next(values, count);\n} catch (OrcCorruptionException e) {\n    if (e.getMessage().contains(\"Reading RLE byte got EOF\")) {\n        log.error(\"ORC file truncated mid-RLE-run: {}\", path, e);\n        alerts.fire(Severity.HIGH, path);\n    }\n    throw e;\n}","preventionTips":["Enable end-to-end checksums on the storage layer.","Re-download files that fail checksum and retry the query.","Never snapshot ORC files while an insert is in flight.","Detect truncation early: file length must match footer-declared content length."],"tags":["orc","corruption","rle","eof","truncated-file"],"backgroundTag":"orc-file-corruption","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}