prestodb/presto · error · ParquetDecodingException
not a valid mode
Error message
not a valid mode
What it means
ParquetDecodingException thrown by DefinitionLevelDecoder.readNext() when the internal Mode enum is neither RLE nor PACKED — the decoder's current buffer state was created with an unknown mode. In practice this indicates corrupted definition-level data or a decoder state bug, since modes are only set from RLE/packed headers.
Source
Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/batchreader/decoders/DefinitionLevelDecoder.java:66
int chunkSize = Math.min(remainingToCopy, currentCount);
switch (mode) {
case RLE: {
int rleValue = currentValue;
int endIndex = destinationIndex + chunkSize;
while (destinationIndex < endIndex) {
values[destinationIndex] = rleValue;
destinationIndex++;
}
break;
}
case PACKED: {
System.arraycopy(currentBuffer, currentBuffer.length - currentCount, values, destinationIndex, chunkSize);
destinationIndex += chunkSize;
break;
}
default:
throw new ParquetDecodingException("not a valid mode " + mode);
}
currentCount -= chunkSize;
remainingToCopy -= chunkSize;
}
checkState(remainingToCopy == 0, "Failed to copy the requested number of DLs");
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Validate the file with parquet-tools; regenerate if the page is corrupt.
- Check the page's definition-level header bytes (bit width, RLE/packed selector) for corruption.
- Upgrade Presto — header-parsing robustness fixes exist across versions.
- If the writer is in-house, ensure it writes valid RLE-encoded definition levels per spec.
Example fix
// before
DLDecoder dl = pageDecoder.getDefinitionLevelDecoder(); // later throws: not a valid mode X
// after
try {
dl = pageDecoder.getDefinitionLevelDecoder();
} catch (ParquetDecodingException e) {
throw new RuntimeException("Corrupt definition levels in " + parquetPath, e);
} Defensive patterns
Strategy: validation
Validate before calling
// sanity-check the definition-level RLE header before decoding
int bitWidth = buffer[0] & 0xFF;
if (bitWidth > 8) throw new IllegalStateException("Invalid DL bit width " + bitWidth + " in " + path);
Try / catch
try {
chunk = reader.readNext();
} catch (ParquetDecodingException e) {
if (e.getMessage().startsWith("not a valid mode")) {
// corrupt definition levels: quarantine file, regenerate
}
throw e;
} Prevention
- Validate files with parquet-tools before querying
- Ensure writers emit spec-compliant RLE level data
- Keep the reader version current (header-parsing fixes)
- Regenerate files with corrupt level headers instead of retrying
When it happens
Trigger: readNext() copies definition levels from the current buffer in chunks; if mode is not MODE.RLE or MODE.PACKED when copying, the default case throws. Only reachable if mode was parsed from a malformed RLE header or constructed incorrectly.
Common situations: Corrupted definition-level byte stream (bad RLE bit-width/header bytes); truncated page data; files from writers emitting non-standard level encodings.
Related errors
- We didn't read correct number of definitionLevels
- Still remaining to be read in current batch.
- Still remaining to be read in current batch.
- Still remaining to be read in current batch.
- Corrupted Parquet file: extra %d values to be consumed when
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e1ac37962deabd1b.
Report an issue: GitHub.