apache/iceberg · error · RuntimeIOException
Problem reading ORC file
Error message
Problem reading ORC file %s
What it means
VectorizedRowBatchIterator lazily fetches the next ORC RowBatch in advance(). If the underlying ORC reader throws IOException while reading the next batch, it is wrapped in RuntimeIOException with the file location. This turns a checked I/O failure during scan into a runtime error for the iterator API.
Solutions
- Inspect the wrapped cause (ioe) to identify the storage-layer failure and fix it (network, permissions, throttling).
- Verify file integrity; if truncated/corrupt, restore or rewrite the data file (e.g. Iceberg rewrite_data_files after fixing the source).
- Retry the scan with engine-level retries; consider enabling Iceberg's task retry or re-running the failed Spark/Flink task.
- If files are being deleted concurrently, ensure snapshot expiry/rewrite jobs don't remove files still needed by running queries.
Example fix
// before: assuming the file is fine
TableScan scan = table.newScan().planTasks();
// after: validate/rescan on RuntimeIOException
try {
scan.planTasks();
} catch (RuntimeIOException e) {
LOG.error("ORC read failed for {}: {}", e.getFileLocation(), e.getCause());
// verify file exists/integrity, then retry or rewrite the file
} Defensive patterns
Strategy: retry
Validate before calling
// Verify file readability before scanning
try (ORCFileReader r = new ORCFileReader(file.io().newInput(file.location()), ...)) {
Preconditions.checkArgument(r.rows() > 0 || file.recordCount() == 0);
} Try / catch
try {
iterator.hasNext();
} catch (RuntimeIOException e) {
LOG.error("ORC scan failed for {}", e.getCause());
// inspect cause: S3Exception / EOFException etc., retry or fail task
} Prevention
- Avoid querying files during snapshot expiry or rewrite jobs
- Set storage client retries (S3/HDFS) for transient IO errors
- Validate file integrity after copying/bulk-loading data
When it happens
Trigger: Calling hasNext() or next() on VectorizedRowBatchIterator when rows.nextBatch(batch) fails — corrupt/truncated ORC file, decompression failure, or storage (HDFS/S3) read errors mid-scan.
Common situations: Truncated files from failed writes; S3/HDFS network interruptions or throttling during long scans; checksum/corruption errors from object storage; file deleted or re-written concurrently while being scanned.
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
- Can't create file
- Can't get Stripe's length from the file writer with path
- Failed to get ORC rows for file
- Failed to get statistics from writer
- Failed to get stripe information from writer for
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/5f01b3f31b1cec3d.
Report an issue: GitHub.
Appendix: source
Thrown at orc/src/main/java/org/apache/iceberg/orc/VectorizedRowBatchIterator.java:60
VectorizedRowBatchIterator(
String fileLocation, TypeDescription schema, RecordReader rows, int recordsPerBatch) {
this.fileLocation = fileLocation;
this.rows = rows;
this.batch = schema.createRowBatch(recordsPerBatch);
}
@Override
public void close() throws IOException {
rows.close();
}
private void advance() {
if (!advanced) {
try {
batchOffsetInFile = rows.getRowNumber();
rows.nextBatch(batch);
} catch (IOException ioe) {
throw new RuntimeIOException(ioe, "Problem reading ORC file %s", fileLocation);
}
advanced = true;
}
}
@Override
public boolean hasNext() {
advance();
return batch.size > 0;
}
@Override
public Pair<VectorizedRowBatch, Long> next() {
// make sure we have the next batch
advance();
// mark it as used
advanced = false;
return Pair.of(batch, batchOffsetInFile);View on GitHub (pinned to 86d9c8fc54)