apache/iceberg · error · ParquetDecodingException

Failed to read from input stream

Error message

Failed to read from input stream

What it means

While decoding an RLE/bit-packed page, the underlying input stream threw an IOException; the reader wraps it in ParquetDecodingException with this message and the cause attached. It indicates the page bytes could not be read from the input.

Solutions

  1. Retry the scan if the cause is a transient I/O error (S3/HDFS).
  2. Re-validate and regenerate the source Parquet file if it is truncated or corrupt.
  3. Check cause chain (ParquetDecodingException.getCause) to distinguish I/O errors from corruption.
Defensive patterns

Strategy: retry

Try / catch

// catch (ParquetDecodingException e) {
//   if (e.getCause() instanceof IOException) { retryWithBackoff(); } // transient I/O
//   else throw e; // corruption
// }

Prevention

When it happens

Trigger: readNextGroup reading past the end of a truncated page, network/filesystem I/O failure mid-scan, or corrupt Parquet footer offsets.

Common situations: Truncated files from failed writes, HDFS/S3 transient errors during long scans, mismatched file checksums.

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/38ecc1a4fc869391. Report an issue: GitHub.

Appendix: source

Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/parquet/BaseVectorizedParquetValuesReader.java:209

          this.currentCount = numGroups * 8;
          if (this.packedValuesBuffer.length < this.currentCount) {
            this.packedValuesBuffer = new int[this.currentCount];
          }
          packedValuesBufferIdx = 0;
          int valueIndex = 0;
          while (valueIndex < this.currentCount) {
            // values are bit packed 8 at a time, so reading bitWidth will always work
            ByteBuffer buffer = inputStream.slice(bitWidth);
            this.packer.unpack8Values(
                buffer, buffer.position(), this.packedValuesBuffer, valueIndex);
            valueIndex += 8;
          }
          return;
        default:
          throw new ParquetDecodingException("not a valid mode " + this.mode);
      }
    } catch (IOException e) {
      throw new ParquetDecodingException("Failed to read from input stream", e);
    }
  }

  @Override
  public boolean readBoolean() {
    return this.readInteger() != 0;
  }

  @Override
  public void skip() {
    throw new UnsupportedOperationException();
  }

  @Override
  public int readValueDictionaryId() {
    return readInteger();
  }

View on GitHub (pinned to 86d9c8fc54)