apache/iceberg · error · NotFoundException
Failed to open file
Error message
Failed to open file: %s
What it means
ContentCache.newStream wraps a FileNotFoundException from the cached-stream path into a NotFoundException, meaning the file could not be opened even though a cached read was attempted. Any other IOException falls back to the uncached delegate stream instead of failing.
Solutions
- Verify the file location exists in storage (ls/stat the object) before or at read time.
- Re-plan the scan to get a fresh snapshot; the file may have been expired.
- Check for concurrent table maintenance (expireSnapshots/rewriteDataFiles) racing readers.
- Fix path/region configuration if the location is systematically wrong.
Example fix
// before
SeekableInputStream in = cacheFile.newStream(); // NotFoundException
// after
if (!io.newInputFile(location).exists()) {
LOG.warn("File {} missing, re-planning scan", location);
return replanAndRead(location);
}
SeekableInputStream in = cacheFile.newStream(); Defensive patterns
Strategy: fallback
Validate before calling
boolean exists = io.newInputFile(location).exists();
if (!exists) { replanOrSkip(location); } Try / catch
try {
return cachedFile.newStream();
} catch (NotFoundException e) {
LOG.warn("File {} not found, falling back to replan", location);
return replannedFile.newStream();
} Prevention
- Don't expire snapshots/rewrite files while long scans are running
- Pin reads to a snapshot ID to avoid reading expired files
- Verify locations after cloning/copying tables across buckets
- Watch for eventual-consistency lag on S3-compatible stores
When it happens
Trigger: Calling newStream() on a caching InputFile whose underlying file is missing (deleted between planning and read, wrong path, or not yet visible), and cachedStream() propagates FileNotFoundException.
Common situations: Reading a data file deleted by compaction/expiry while a long-running scan still references it; mistyped or stale file location; eventual-consistency lag after write in S3-compatible stores.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Failed to open Parquet file
- Failed to read bytes: bytes in stream
- An error occurred while aborting the stream
- An error occurred while closing the stream
- Bulk deletion failed
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/adcd79c01fc84282.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/io/ContentCache.java:214
}
/**
* Opens a new {@link SeekableInputStream} for the underlying data file, either from cache or
* from the inner FileIO.
*
* <p>If data file is not cached yet, and it can fit in the cache, the file content will be
* cached first before returning a {@link ByteBufferInputStream}. Otherwise, return a new
* SeekableInputStream from the inner FIleIO.
*
* @return a {@link ByteBufferInputStream} if file exist in the cache or can fit in the cache.
* Otherwise, return a new SeekableInputStream from the inner FIleIO.
*/
@Override
public SeekableInputStream newStream() {
try {
return cachedStream();
} catch (FileNotFoundException e) {
throw new NotFoundException(e, "Failed to open file: %s", input.location());
} catch (IOException e) {
return input.newStream();
}
}
@Override
public String location() {
return input.location();
}
@Override
public boolean exists() {
FileContent buf = contentCache.cache.getIfPresent(input.location());
return buf != null || input.exists();
}
private SeekableInputStream cachedStream() throws IOException {
try {View on GitHub (pinned to 86d9c8fc54)