apache/iceberg · error · NotFoundException
Location does not exist: %s
Error message
Location does not exist: %s
What it means
S3InputStream throws a NotFoundException when S3 responds with NoSuchKeyException while opening the object input stream. It means the S3 key backing the given Iceberg location no longer exists, so the stream cannot be opened (or re-opened after a retry).
Source
Thrown at aws/src/main/java/org/apache/iceberg/aws/s3/S3InputStream.java:263
private void openStream() throws IOException {
openStream(false);
}
private void openStream(boolean closeQuietly) throws IOException {
GetObjectRequest.Builder requestBuilder =
GetObjectRequest.builder()
.bucket(location.bucket())
.key(location.key())
.range(String.format("bytes=%s-", pos));
S3RequestUtil.configureEncryption(s3FileIOProperties, requestBuilder);
closeStream(closeQuietly);
try {
stream = s3.getObject(requestBuilder.build(), ResponseTransformer.toInputStream());
} catch (NoSuchKeyException e) {
throw new NotFoundException(e, "Location does not exist: %s", location);
}
}
@VisibleForTesting
void resetForRetry() throws IOException {
openStream(true);
}
private void closeStream(boolean closeQuietly) throws IOException {
if (stream != null) {
// if we aren't at the end of the stream, and the stream is abortable, then
// call abort() so we don't read the remaining data with the Apache HTTP client
abortStream();
try {
stream.close();
} catch (IOException e) {
if (closeQuietly) {
stream = null;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify the S3 key exists with s3FileIO (io.newInputFile(location).exists()) before reading.
- Check whether the file was deleted concurrently by cleanup jobs (expireSnapshots, removeOrphanFiles) and adjust retention.
- Re-read from a fresh, current table snapshot instead of a stale cached file reference.
- Check for typos or stale catalog entries producing a wrong location URI.
Example fix
// before
InputFile in = io.newInputFile("s3://bucket/stale/data.parquet");
in.newStream(); // NotFoundException
// after
InputFile in = io.newInputFile("s3://bucket/stale/data.parquet");
if (!in.exists()) {
throw new IllegalStateException("File missing; refresh table snapshot");
}
in.newStream(); Defensive patterns
Strategy: validation
Validate before calling
// Java
InputFile in = io.newInputFile(location);
if (!in.exists()) {
throw new IllegalStateException("Object missing at " + location + "; refresh snapshot or restore cleanup retention");
} Try / catch
// Java
try {
in.newStream();
} catch (NotFoundException e) {
LOG.warn("Object vanished: {}", location);
// re-plan read from current table snapshot or surface a user-facing error
} Prevention
- Check file existence before long-running reads of external references
- Keep expireSnapshots/removeOrphanFiles retention longer than maximum job duration
- Re-resolve file locations from the latest table snapshot instead of caching them
When it happens
Trigger: Calling openStream (directly or via resetForRetry after a transient failure) when the underlying S3 object was deleted or never written; s3.getObject returns NoSuchKeyException.
Common situations: Another process expired/deleted the file (e.g. orphan cleanup, expireSnapshots) while it was being read; typos in the location URI; reading data files from a table whose metadata was rolled back; eventual consistency races in custom catalogs.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Location already exists: %s
- Failed to create file: %s
- Failed to delete: %s
- %s does not expose configuration properties
- Failed to create S3 analytics accelerator input stream for:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/9fdc85a7d4f29edf.
Report an issue: GitHub.