apache/iceberg · error · NotFoundException
Failed to open input stream for file: %s
Error message
Failed to open input stream for file: %s
What it means
HadoopInputFile.newStream opens a SeekableInputStream via fs.open(path). FileNotFoundException becomes NotFoundException (a missing file), while any other IOException becomes this RuntimeIOException. Both use the same 'Failed to open input stream' message, so check the exception type/cause to distinguish missing-file from I/O trouble.
Source
Thrown at core/src/main/java/org/apache/iceberg/hadoop/HadoopInputFile.java:187
}
}
return stat;
}
@Override
public long getLength() {
if (length == null) {
this.length = lazyStat().getLen();
}
return length;
}
@Override
public SeekableInputStream newStream() {
try {
return HadoopStreams.wrap(fs.open(path));
} catch (FileNotFoundException e) {
throw new NotFoundException(e, "Failed to open input stream for file: %s", path);
} catch (IOException e) {
throw new RuntimeIOException(e, "Failed to open input stream for file: %s", path);
}
}
@Override
public Configuration getConf() {
return conf;
}
@Override
public void serializeConfWith(
Function<Configuration, SerializableSupplier<Configuration>> confSerializer) {
throw new UnsupportedOperationException("Cannot serialize a Hadoop input file: " + location());
}
public FileSystem getFileSystem() {
return fs;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check the exception cause: FileNotFoundException means the file is gone — refresh table metadata or restore the file.
- Other causes (throttling, auth, permissions): refresh credentials, verify permissions, and retry with backoff.
- Ensure cleanup jobs don't delete files still covered by active snapshots; set proper retention windows.
- Confirm scheme/authority/region configuration matches the storage where files were written.
- Use table rollback to a snapshot whose files still exist if files were permanently lost.
Example fix
// before
SeekableInputStream in = io.newInputFile(path).newStream();
// after
try {
SeekableInputStream in = io.newInputFile(path).newStream();
} catch (NotFoundException e) {
table.refresh(); // metadata may reference a deleted file
throw e;
} catch (RuntimeIOException e) {
// transient FS/auth issue: refresh creds and retry
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
InputFile f = io.newInputFile(path);
if (!f.exists()) { /* avoid newStream: file missing */ } Try / catch
try (SeekableInputStream in = io.newInputFile(path).newStream()) {
// read
} catch (NotFoundException e) {
// file missing: refresh metadata / rollback snapshot
} catch (RuntimeIOException e) {
// transient IO/auth: refresh creds, retry with backoff
} Prevention
- Always open streams inside try-with-resources.
- Ensure cleanup jobs don't delete files for live snapshots.
- Refresh credentials/tokens for jobs longer than the token lifetime.
- Verify scheme/authority/region correctness before deployment.
When it happens
Trigger: Calling newStream() on a file deleted between exists() and open, on a path with wrong scheme/authority, or when the FS client fails (auth expiry, throttling, permission denied, checksum errors on HDFS).
Common situations: Readers racing with expireSnapshots/orphan cleanup; long-running Spark jobs whose Kerberos or cloud credentials expire; S3 throttling during large parallel reads; cluster decommissioning making files unreachable.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- Failed to create Parquet input file for %s
- Failed to open file: %s
- Failed to list tables under: %s
- Failed to delete file: %s
- Create namespace failed: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8a03835bc920bcc6.
Report an issue: GitHub.