apache/iceberg · error · ParquetDecodingException

could not read page %s in col %s

Error message

could not read page %s in col %s

What it means

BasePageIterator.initFromPage(DataPageV1) initializes repetition/definition level readers and the data reader for a Parquet page. Any IOException during page decoding is rethrown as ParquetDecodingException identifying the page and column. It indicates a corrupt, truncated, or unreadable page.

Source

Thrown at parquet/src/main/java/org/apache/iceberg/parquet/BasePageIterator.java:141

        });
    this.triplesRead = 0;
    this.hasNext = triplesRead < triplesCount;
  }

  protected void initFromPage(DataPageV1 initPage) {
    this.triplesCount = initPage.getValueCount();
    try {
      BytesInput bytes = initPage.getBytes();
      LOG.debug("page size {} bytes and {} records", bytes.size(), triplesCount);
      LOG.debug("reading repetition levels at 0");
      ByteBufferInputStream in = bytes.toInputStream();
      initRepetitionLevelsReader(initPage, desc, in, triplesCount);
      LOG.debug("reading definition levels at {}", in.position());
      initDefinitionLevelsReader(initPage, desc, in, triplesCount);
      LOG.debug("reading data at {}", in.position());
      initDataReader(initPage.getValueEncoding(), in, initPage.getValueCount());
    } catch (IOException e) {
      throw new ParquetDecodingException("could not read page " + initPage + " in col " + desc, e);
    }
  }

  protected void initFromPage(DataPageV2 initPage) {
    this.triplesCount = initPage.getValueCount();
    try {
      initRepetitionLevelsReader(initPage, desc);
      initDefinitionLevelsReader(initPage, desc);
      LOG.debug("page data size {} bytes and {} records", initPage.getData().size(), triplesCount);
      initDataReader(initPage.getDataEncoding(), initPage.getData().toInputStream(), triplesCount);
    } catch (IOException e) {
      throw new ParquetDecodingException("could not read page " + initPage + " in col " + desc, e);
    }
  }

  public void setDictionary(Dictionary dict) {
    this.dictionary = dict;
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Validate the file with a Parquet metadata tool to locate the corrupt column chunk/page.
  2. Restore the file from the source, or rewrite the affected files (Iceberg rewrite_data_files / compaction) from a good copy.
  3. If the cause is storage-level (network/permissions), fix the storage issue and retry the query.
  4. Check writer versions: files written by known-buggy writers may need re-encoding with a fixed writer.

Example fix

// before: query fails mid-scan with ParquetDecodingException
// after: rewrite corrupted files
spark.sql("CALL catalog.system.rewrite_data_files(table => 'db.tbl', options => map('rewrite-all','true'))");
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap pre-flight: read footer/metadata to detect truncation
try (ParquetFileReader pfr = ParquetFileReader.open(file.io().newInput(file.location()))) {
  Preconditions.checkNotNull(pfr.getFooter());
}

Try / catch

try {
  reader.read();
} catch (ParquetDecodingException e) {
  LOG.error("Corrupt page in column {}: {}", e.getMessage(), e.getCause());
  // quarantine/rewrite the file, do not silently skip rows
}

Prevention

When it happens

Trigger: Called from the column reader's visit() when advancing to the next page: page bytes cannot be read from the input stream — truncated file, bad page header values, decompression errors, or storage I/O failure.

Common situations: Corrupted Parquet files from failed/interrupted writes; S3/HDFS read errors mid-scan; files damaged by external compaction or network tooling; version incompatibilities causing misparse of pages.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/9831a8c8616c5184. Report an issue: GitHub.