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

BooleanBatchStreamReader.readBlock throws OrcCorruptionException when every value in the batch is null (dataStream is null) yet the PRESENT stream is also missing. Per ORC spec, a column containing nulls must include a present stream to encode the null mask, so its absence makes null positions undeterminable.

Source

Thrown at presto-orc/src/main/java/com/facebook/presto/orc/reader/BooleanBatchStreamReader.java:120

                if (dataStream == null) {
                    throw new OrcCorruptionException(streamDescriptor.getOrcDataSourceId(), "Value is not null but data stream is not present");
                }
                dataStream.skip(readOffset);
            }
        }

        if (dataStream == null && presentStream != null) {
            presentStream.skip(nextBatchSize);
            Block nullValueBlock = RunLengthEncodedBlock.create(BOOLEAN, null, nextBatchSize);
            readOffset = 0;
            nextBatchSize = 0;
            return nullValueBlock;
        }

        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(BOOLEAN, 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(BOOLEAN, null, nextBatchSize);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Regenerate the ORC file with a spec-compliant writer so null-carrying columns include present streams.
  2. Validate with orc-tools and identify the non-conformant writer/version; upgrade it.
  3. Check intermediate storage/compression layers for stream loss (e.g. partial uploads).
  4. Catch OrcCorruptionException in the reader and skip/fail the split gracefully.

Example fix

// before
Block b = streamReader.readBlock(); // throws
// after
try { b = streamReader.readBlock(); } catch (OrcCorruptionException e) { b = RunLengthEncodedBlock.create(BOOLEAN, null, size); }
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm present streams exist for nullable columns
// orc-tools meta file.orc | grep PRESENT

Try / catch

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

Prevention

When it happens

Trigger: Reading a BOOLEAN column where dataStream == null (all values expected null) and presentStream == null during readBlock of the next batch.

Common situations: Malformed ORC files written without present streams despite null data; files produced by non-conformant or buggy writers; manual stream stripping/corruption during storage transfer.

Related errors


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