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

  1. Verify the S3 key exists with s3FileIO (io.newInputFile(location).exists()) before reading.
  2. Check whether the file was deleted concurrently by cleanup jobs (expireSnapshots, removeOrphanFiles) and adjust retention.
  3. Re-read from a fresh, current table snapshot instead of a stale cached file reference.
  4. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/9fdc85a7d4f29edf. Report an issue: GitHub.