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

  1. Validate the file with parquet-tools; regenerate if the page is corrupt.
  2. Check the page's definition-level header bytes (bit width, RLE/packed selector) for corruption.
  3. Upgrade Presto — header-parsing robustness fixes exist across versions.
  4. 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

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


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