prestodb/presto · error · OrcCorruptionException

Value is null but present stream is missing

Error message

Value is null but present stream is missing

What it means

ByteBatchStreamReader.readBlock throws OrcCorruptionException when the byte data stream is absent (implying all-null values) but the PRESENT stream, required to encode which rows are null, is also missing. Without a present stream the reader cannot determine null positions, so the file is deemed corrupt.

Source

Thrown at presto-orc/src/main/java/com/facebook/presto/orc/reader/ByteBatchStreamReader.java:113

        if (readOffset > 0) {
            if (presentStream != null) {
                // skip ahead the present bit reader, but count the set bits
                // and use this as the skip size for the data reader
                readOffset = presentStream.countBitsSet(readOffset);
            }
            if (readOffset > 0) {
                if (dataStream == null) {
                    throw new OrcCorruptionException(streamDescriptor.getOrcDataSourceId(), "Value is not null but data stream is missing");
                }
                dataStream.skip(readOffset);
            }
        }

        Block block;
        if (dataStream == null) {
            if (presentStream == null) {
                throw new OrcCorruptionException(streamDescriptor.getOrcDataSourceId(), "Value is null but present stream is missing");
            }
            presentStream.skip(nextBatchSize);
            block = RunLengthEncodedBlock.create(TINYINT, null, nextBatchSize);
        }
        else if (presentStream == null) {
            block = readNonNullBlock();
        }
        else {
            boolean[] isNull = new boolean[nextBatchSize];
            int nullCount = presentStream.getUnsetBits(nextBatchSize, isNull);
            if (nullCount == 0) {
                block = readNonNullBlock();
            }
            else if (nullCount != nextBatchSize) {
                block = readNullBlock(isNull, nextBatchSize - nullCount);
            }
            else {
                block = RunLengthEncodedBlock.create(TINYINT, null, nextBatchSize);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Rewrite the file with a spec-compliant ORC writer so present streams are emitted.
  2. Validate the file with orc-tools and identify/upgrade the faulty writer.
  3. Check whether a column type change made the reader expect a stream layout the writer never produced.
  4. Catch OrcCorruptionException in the connector layer and route the split to an error handler.

Example fix

// before: reading a non-conformant file
Block b = reader.readBlock(); // throws
// after: re-encode the file
// INSERT INTO fixed_table SELECT * FROM broken_table;  -- rewrites with present streams
Defensive patterns

Strategy: try-catch

Validate before calling

// validate ORC file structure before query: orc-tools meta file.orc

Try / catch

try { block = streamReader.readBlock(); } catch (OrcCorruptionException e) { logAndSkipSplit(e); }

Prevention

When it happens

Trigger: readBlock on a BYTE/TINYINT column where dataStream == null and presentStream == null for the upcoming batch.

Common situations: Non-conformant ORC writers omitting present streams on all-null columns; schema/type changes in the writer pipeline; corrupted footers causing stream misclassification.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/de6f721862e84666. Report an issue: GitHub.