prestodb/presto · error · ParquetDecodingException
not a valid mode
Error message
not a valid mode
What it means
BinaryRLEDictionaryValuesDecoder.readNext fills value buffers from RLE/bit-packed dictionary indices; the mode switch only supports RLE and PACKED_BIT_PACKED. An unknown mode in the index stream's run header makes the dictionary-id data undecodable, so a ParquetDecodingException is thrown with this.mode. It indicates corrupt or unsupported dictionary index data.
Source
Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/batchreader/decoders/rle/BinaryRLEDictionaryValuesDecoder.java:80
final int rleValueLength = dictionary.getLength(rleValue);
while (destinationIndex < endIndex) {
dictionaries[destinationIndex++] = rleValue;
}
bufferSize += (rleValueLength * numEntriesToFill);
break;
}
case PACKED: {
final int[] localBuffer = currentBuffer;
final BinaryBatchDictionary localDictionary = dictionary;
for (int srcIndex = currentBuffer.length - currentCount; destinationIndex < endIndex; srcIndex++, destinationIndex++) {
int dictionaryId = localBuffer[srcIndex];
dictionaries[destinationIndex] = dictionaryId;
bufferSize += localDictionary.getLength(dictionaryId);
}
break;
}
default:
throw new ParquetDecodingException("not a valid mode " + this.mode);
}
currentCount -= numEntriesToFill;
remainingToCopy -= numEntriesToFill;
}
checkState(remainingToCopy == 0, "Invalid read size request");
return new RLEValueBuffer(bufferSize, dictionaries);
}
@Override
public int readIntoBuffer(byte[] byteBuffer, int bufferIndex, int[] offsets, int offsetIndex, ValueBuffer valueBuffer)
{
checkArgument(byteBuffer.length - bufferIndex >= valueBuffer.getBufferSize(), "not enough space in the input buffer");
RLEValueBuffer rleValueBuffer = (RLEValueBuffer) valueBuffer;
final int[] dictionaryIds = rleValueBuffer.getDictionaryIds();
final int numEntries = dictionaryIds.length;
View on GitHub (pinned to 55bb57d202)
Solutions
- Validate the column chunk with parquet-tools (it will also fail if data is corrupt)
- Disable dictionary reading issues by rewriting the file without dictionary encoding or with a standard writer
- Restore the file from a clean source and compare checksums
- Upgrade presto-parquet if a newer writer encoding is involved; otherwise file a bug with file metadata
Example fix
// before: file with corrupt dictionary index header // after: rewrite without dictionary encoding to sidestep the bad header // parquet.writer.dictionary=false (writer config) or rewrite via Spark/Trino
Defensive patterns
Strategy: try-catch
Validate before calling
// parquet-tools meta file.parquet | grep <column> # confirm RLE_DICTIONARY/PLAIN_DICTIONARY and intact chunk sizes
Try / catch
try {
decoder.readNext(batchSize);
} catch (ParquetDecodingException e) {
if (e.getMessage().startsWith("not a valid mode")) {
// retry against a re-written copy of the file; do not loop-retry the same bytes
}
throw e;
} Prevention
- Validate dictionary-encoded columns at ingest with parquet-tools
- Rewrite suspect files without dictionary encoding to isolate header corruption
- Enforce checksum verification in data pipelines
- Keep writer and reader versions compatible
When it happens
Trigger: readNext() reaches the default branch because a run header in the dictionary-index stream encodes a mode outside Mode.RLE/Mode.PACKED_BIT_PACKED.
Common situations: Corrupted dictionary-encoded column chunks; files produced by writers emitting non-standard hybrid headers; byte-offset misalignment after earlier decode errors causing headers to be read at wrong positions.
Related errors
- not a valid mode
- not a valid mode
- not a valid mode
- not a valid mode
- could not decode the dictionary for
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1e7b5f5cfb601589.
Report an issue: GitHub.