prestodb/presto · error · PrestoException

PARQUET_IO_READ_ERROR

PARQUET_IO_READ_ERROR

Error message

Error reading parquet page 

What it means

PrestoException (PARQUET_IO_READ_ERROR) thrown by Decoders.readFlatPage() when reading a flat (non-nested) data page — V1 or V2 — throws an IOException. It converts stream/decode I/O failures on a single page into a typed error naming the page and column, preserving the cause.

Source

Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/batchreader/decoders/Decoders.java:112

import static org.apache.parquet.bytes.BytesUtils.readIntLittleEndianOnOneByte;
import static org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.BOOLEAN;

public class Decoders
{
    private Decoders()
    {
    }

    public static FlatDecoders readFlatPage(DataPage page, RichColumnDescriptor columnDescriptor, Dictionary dictionary)
    {
        try {
            if (page instanceof DataPageV1) {
                return readFlatPageV1((DataPageV1) page, columnDescriptor, dictionary);
            }
            return readFlatPageV2((DataPageV2) page, columnDescriptor, dictionary);
        }
        catch (IOException e) {
            throw new PrestoException(PARQUET_IO_READ_ERROR, "Error reading parquet page " + page + " in column " + columnDescriptor, e);
        }
    }

    private static ValuesDecoder createValuesDecoder(ColumnDescriptor columnDescriptor, Dictionary dictionary, int valueCount, ParquetEncoding encoding, byte[] buffer, int offset, int length)
            throws IOException
    {
        final PrimitiveTypeName type = columnDescriptor.getPrimitiveType().getPrimitiveTypeName();

        if (encoding == PLAIN) {
            switch (type) {
                case BOOLEAN:
                    return new BooleanPlainValuesDecoder(buffer, offset, length);
                case INT32:
                    if (isShortDecimalType(columnDescriptor)) {
                        return new Int32ShortDecimalPlainValuesDecoder(buffer, offset, length);
                    }
                case FLOAT:
                    return new Int32PlainValuesDecoder(buffer, offset, length);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the cause IOException to distinguish truncation vs storage failure.
  2. Verify the file integrity with parquet-tools; regenerate if corrupt.
  3. Retry transient storage/network failures.
  4. Compare page metadata (uncompressed/compressed sizes) with actual chunk bytes to confirm truncation.

Example fix

// before
ValuesBlock vb = Decoders.readFlatPage(page, columnDescriptor, dictionary); // throws PARQUET_IO_READ_ERROR
// after
try {
    vb = Decoders.readFlatPage(page, columnDescriptor, dictionary);
} catch (PrestoException e) {
    log.error("Failed page %s in column %s", page, columnDescriptor, e);
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure page bytes are present in the buffer before decoding
if (page.getBufferSize() > chunkBuffer.remaining()) throw new IllegalStateException("Truncated page in " + path);

Try / catch

try {
    vb = Decoders.readFlatPage(page, columnDescriptor, dictionary);
} catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("PARQUET_IO_READ_ERROR")) {
        // log page + column, check cause IOException, retry transient failures
    }
    throw e;
}

Prevention

When it happens

Trigger: readFlatPage() is invoked per data page while decoding a column chunk; any IOException from readFlatPageV1/readFlatPageV2 (buffer wrap failures, RLE/dictionary decoding I/O, truncated page bytes) is wrapped here.

Common situations: Truncated page bytes from a corrupted or incomplete file; storage-layer read failures; pages whose declared length exceeds available bytes in the chunk.

Related errors


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