prestodb/presto · error · OrcCorruptionException
Dictionary is not empty but dictionary length stream is not
Error message
Dictionary is not empty but dictionary length stream is not present
What it means
During openRowGroup, the reader found stripeDictionarySize > 0 (the stripe dictionary holds entries) but the DICTIONARY_LENGTH stream is absent, so entry lengths cannot be decoded. The file's stream layout contradicts its metadata, so it is flagged as corrupt.
Source
Thrown at presto-orc/src/main/java/com/facebook/presto/orc/reader/SliceDictionaryBatchStreamReader.java:228
}
}
private void openRowGroup()
throws IOException
{
// read the dictionary
if (!stripeDictionaryOpen) {
if (stripeDictionarySize > 0) {
// resize the dictionary lengths array if necessary
if (stripeDictionaryLength.length < stripeDictionarySize) {
stripeDictionaryLength = new int[stripeDictionarySize];
systemMemoryContext.setBytes(sizeOf(stripeDictionaryLength));
}
// read the lengths
LongInputStream lengthStream = stripeDictionaryLengthStreamSource.openStream();
if (lengthStream == null) {
throw new OrcCorruptionException(streamDescriptor.getOrcDataSourceId(), "Dictionary is not empty but dictionary length stream is not present");
}
lengthStream.next(stripeDictionaryLength, stripeDictionarySize);
long dataLength = 0;
for (int i = 0; i < stripeDictionarySize; i++) {
dataLength += stripeDictionaryLength[i];
}
// we must always create a new dictionary array because the previous dictionary may still be referenced
stripeDictionaryData = new byte[toIntExact(dataLength)];
systemMemoryContext.setBytes(sizeOf(stripeDictionaryData));
// add one extra entry for null
stripeDictionaryOffsetVector = new int[stripeDictionarySize + 2];
systemMemoryContext.setBytes(sizeOf(stripeDictionaryOffsetVector));
// read dictionary values
ByteArrayInputStream dictionaryDataStream = stripeDictionaryDataStreamSource.openStream();View on GitHub (pinned to 55bb57d202)
Solutions
- Validate the ORC file with orc-tools to confirm the missing DICTIONARY_LENGTH stream.
- Regenerate the file or restore from backup.
- Ensure no concurrent writers overwrite the file while it is being read (write-then-rename pattern).
- Check the producing writer version for known dictionary-encoding bugs.
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm DICTIONARY_LENGTH stream exists when dictionary encoding is used // orc-tools meta file.orc | grep DICTIONARY_LENGTH
Try / catch
try {
return reader.readBlock();
} catch (OrcCorruptionException e) {
log.error("Dictionary length stream missing in %s", e.getOrcDataSourceId());
throw new DataIntegrityException("ORC dictionary encoding incomplete", e);
} Prevention
- Use atomic publish (write to temp path, rename) for ORC output.
- Check writer version for dictionary-encoding bugs before adopting files.
- Validate files at ingest with orc-tools meta.
When it happens
Trigger: readBlock() triggering openRowGroup() on a dictionary-encoded string column with stripeDictionarySize > 0 while stripeDictionaryLengthStreamSource.openStream() returns null.
Common situations: Truncated ORC files missing tail streams; files written by buggy writers that emit dictionary data without lengths; corruption during file transfer or partial overwrite by concurrent writers.
Related errors
- Value is not null but data stream is not present
- Dictionary is not empty but dictionary length stream is not
- Value is not null but data stream is not present
- Value is not null but data stream is missing
- Value is not null but decimal stream is not present
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/2ebe08fc6737368b.
Report an issue: GitHub.