{"record":{"id":"aa69f042a0c13fcb","repo":"apache/iceberg","slug":"could-not-read-levels-in-page-for-col-s","errorCode":null,"errorMessage":"could not read levels in page for col %s","messagePattern":"could not read levels in page for col (.+?)","errorType":"exception","errorClass":"ParquetDecodingException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/BasePageIterator.java","lineNumber":187,"sourceCode":"      this.delegate = delegate;\n    }\n\n    @Override\n    int nextInt() {\n      return delegate.readInteger();\n    }\n  }\n\n  IntIterator newRLEIterator(int maxLevel, BytesInput bytes) {\n    try {\n      if (maxLevel == 0) {\n        return new NullIntIterator();\n      }\n      return new RLEIntIterator(\n          new RunLengthBitPackingHybridDecoder(\n              BytesUtils.getWidthFromMaxInt(maxLevel), bytes.toInputStream()));\n    } catch (IOException e) {\n      throw new ParquetDecodingException(\"could not read levels in page for col \" + desc, e);\n    }\n  }\n\n  static class RLEIntIterator extends IntIterator {\n    private final RunLengthBitPackingHybridDecoder delegate;\n\n    RLEIntIterator(RunLengthBitPackingHybridDecoder delegate) {\n      this.delegate = delegate;\n    }\n\n    @Override\n    int nextInt() {\n      try {\n        return delegate.readInt();\n      } catch (IOException e) {\n        throw new ParquetDecodingException(e);\n      }\n    }","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/BasePageIterator.java#L169-L205","documentation":"BasePageIterator.newRLEIterator builds an RLE/bit-packing integer iterator for repetition or definition levels. If reading the level bytes throws IOException it is wrapped in ParquetDecodingException. This indicates the level data in the page is unreadable or corrupt.","triggerScenarios":"Called from initRepetitionLevelsReader/initDefinitionLevelsReader when decoding a page whose repetition/definition level stream cannot be read — corrupt level bytes, wrong width (maxLevel), or truncated buffer.","commonSituations":"Corrupted pages from faulty writers or truncated transfers; files damaged in storage; page-level corruption spotted only when scanning columns with optional/repeated fields.","solutions":["Run a parquet validation tool on the file to confirm page-level corruption.","Restore the file from a backup or rewrite the data from the original source.","If corruption came from a specific writer version, re-encode affected files with a fixed writer."],"exampleFix":"// before: scan fails on levels\n// after: rewrite corrupted file from source\nspark.read.parquet(\"good/source\").writeTo(\"db.tbl\").overwritePartitions();","handlingStrategy":"try-catch","validationCode":"// Pre-check column chunk statistics/size vs expected to catch truncation\nif (chunkMeta.getTotalSize() > (fileLength - chunkMeta.getStartOffset())) {\n  throw new IllegalStateException(\"Column chunk truncated for \" + desc);\n}","typeGuard":null,"tryCatchPattern":"try {\n  scanData();\n} catch (ParquetDecodingException e) {\n  if (e.getMessage().contains(\"could not read levels\")) {\n    // page level corruption: quarantine and rewrite file\n  }\n}","preventionTips":["Detect truncation by comparing footer-declared chunk sizes with file length","Restore damaged files from upstream before scanning","Track writer versions and re-encode files from buggy writers"],"tags":["parquet","corrupt-file","levels"],"backgroundTag":"file-read-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}