prestodb/presto · error · ParquetDecodingException

Error reading parquet page in column

Error message

Error reading parquet page  in column 

What it means

readPageV1 wraps any IOException raised while decoding a DataPageV1 — reading repetition/definition levels or initializing the values reader via initDataReader — into a ParquetDecodingException naming the page and column descriptor. It signals that a page's serialized bytes could not be parsed according to the Parquet V1 page format.

Source

Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/reader/AbstractColumnReader.java:312

        remainingValueCountInPage -= totalCount;
        currentValueCount += valuesRead;
    }

    private ValuesReader readPageV1(DataPageV1 page)
    {
        ValuesReader repetitionLevelReader = page.getRepetitionLevelEncoding().getValuesReader(columnDescriptor, REPETITION_LEVEL);
        ValuesReader definitionLevelReader = page.getDefinitionLevelEncoding().getValuesReader(columnDescriptor, DEFINITION_LEVEL);
        repetitionReader = new LevelValuesReader(repetitionLevelReader);
        definitionReader = new LevelValuesReader(definitionLevelReader);
        try {
            ByteBufferInputStream bufferInputStream = ByteBufferInputStream.wrap(page.getSlice().toByteBuffer());
            repetitionLevelReader.initFromPage(page.getValueCount(), bufferInputStream);
            definitionLevelReader.initFromPage(page.getValueCount(), bufferInputStream);
            long firstRowIndex = page.getFirstRowIndex().orElse(-1L);
            return initDataReader(page.getValueEncoding(), bufferInputStream, page.getValueCount(), firstRowIndex);
        }
        catch (IOException e) {
            throw new ParquetDecodingException("Error reading parquet page " + page + " in column " + columnDescriptor, e);
        }
    }

    private ValuesReader readPageV2(DataPageV2 page)
    {
        repetitionReader = buildLevelRLEReader(columnDescriptor.getMaxRepetitionLevel(), page.getRepetitionLevels());
        definitionReader = buildLevelRLEReader(columnDescriptor.getMaxDefinitionLevel(), page.getDefinitionLevels());
        long firstRowIndex = page.getFirstRowIndex().orElse(-1L);
        return initDataReader(page.getDataEncoding(), ByteBufferInputStream.wrap(ImmutableList.of(page.getSlice().toByteBuffer())), page.getValueCount(), firstRowIndex);
    }

    private LevelReader buildLevelRLEReader(int maxLevel, Slice slice)
    {
        if (maxLevel == 0) {
            return new LevelNullReader();
        }

        return new LevelRLEReader(new RunLengthBitPackingHybridDecoder(BytesUtils.getWidthFromMaxInt(maxLevel), slice.getInput()));

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Re-read / re-fetch the file and validate checksums; truncated or corrupted page bytes are the most common cause.
  2. Check the file's compression codec metadata (parquet-tools meta) and ensure the Presto runtime supports that codec (e.g. zstd/LZO availability).
  3. Rewrite the file with a modern writer ( uncompressed or snappy ) to regenerate valid pages.
  4. Upgrade Presto / parquet-mr in case of a known page-parsing incompatibility with the writer version.
  5. Identify the writer via file metadata (created_by) and re-export the data if the writer had a known page-serialization bug.

Example fix

// before
SELECT * FROM corrupt_parquet_table;  -- ParquetDecodingException: Error reading parquet page ...

// after (regenerate the file, e.g. re-export from source)
// $ parquet-tools cat bad.parquet  # confirm corruption locally
// re-export the table, then query the new table
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight integrity check on the source file
// $ parquet-tools meta file.parquet   # throws on malformed pages/metadata

Try / catch

try {
    // read pages / execute query
}
catch (ParquetDecodingException e) {
    if (e.getMessage().startsWith("Error reading parquet page")) {
        logger.error("Unreadable page: {}", e.getMessage());
        // quarantine the file and retry from a verified copy
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: readNextPage -> readPageV1 on a DataPageV1 where uncompressing/parsing the page buffer throws IOException: corrupted or truncated page bytes, wrong compression codec metadata, a page whose declared valueCount exceeds the actual buffer, or a decompression failure.

Common situations: Truncated files from failed S3/HDFS copies; files written with compression codecs the reader's codec stack can't decompress; disk/network corruption; writer bugs producing malformed V1 pages; reading with Presto a file written by an incompatible/buggy writer version.

Related errors


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