apache/beam · error · FileNotFoundException

The specified file does not exist: %s

Error message

The specified file does not exist: %s

What it means

GcsUtilV2.getBlob fetches a Blob via the com.google.cloud.storage.Storage client and throws FileNotFoundException when Storage.get returns null, i.e. the object does not exist (or the caller lacks visibility). StorageExceptions are translated separately.

Source

Thrown at sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV2.java:129

      case 404:
        return new FileNotFoundException(e.getMessage());
      case 409:
        return new FileAlreadyExistsException(gcsPath.toString(), null, e.getMessage());
      default:
        return new IOException(e);
    }
  }

  private IOException translateStorageException(
      String bucketName, @Nullable String blobName, StorageException e) {
    return translateStorageException(GcsPath.fromComponents(bucketName, blobName), e);
  }

  public Blob getBlob(GcsPath gcsPath, BlobGetOption... options) throws IOException {
    try {
      Blob blob = storage.get(gcsPath.getBucket(), gcsPath.getObject(), options);
      if (blob == null) {
        throw new FileNotFoundException(
            String.format("The specified file does not exist: %s", gcsPath.toString()));
      }
      return blob;
    } catch (StorageException e) {
      throw translateStorageException(gcsPath, e);
    }
  }

  public long fileSize(GcsPath gcsPath) throws IOException {
    return getBlob(gcsPath, BlobGetOption.fields(BlobField.SIZE)).getSize();
  }

  /** A class that holds either a {@link Blob} or an {@link IOException}. */
  @AutoValue
  public abstract static class BlobResult {

    /** Returns the {@link Blob}. */
    public abstract @Nullable Blob blob();

View on GitHub (pinned to 12126d8942)

Solutions

  1. Verify the gs:// path exists: gsutil ls <path> or storage.get via console.
  2. Check the file path/template configuration for typos or stale values.
  3. Guard with gcsUtil.expand/gcsUtil.treeList over a directory pattern before calling fileSize/getBlob.
  4. Handle FileNotFoundException at the call site when the file is optional.

Example fix

// before
long size = gcsUtil.fileSize(GcsPath.fromUri(path));
// after
try {
  long size = gcsUtil.fileSize(GcsPath.fromUri(path));
} catch (FileNotFoundException e) {
  LOG.warn("Skipping missing object {}", path);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check existence via listing
List<Metadata> existing = gcsUtil.expand(GcsPath.fromUri(dirPattern));
boolean present = existing.stream()
    .anyMatch(m -> m.resourceId().toString().equals(path.toString()));

Try / catch

try {
  Blob blob = gcsUtil.getBlob(GcsPath.fromUri(uri));
} catch (FileNotFoundException e) {
  // treat as missing: skip, substitute default, or surface config error
}

Prevention

When it happens

Trigger: Any call path through getBlob — fileSize(gcsPath), expand(gcsPath), or blob(...) — where the (bucket, object) pair does not exist, e.g. wrong object path, object deleted, or getBlob called before a write completes.

Common situations: Stale file listing cached by a caller; typos or wrong templated file paths in pipeline options; eventual consistency windows in listing vs. get in concurrent writes; reading a match-generated path that matched zero files is guarded elsewhere but direct paths can 404.

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/766bea8a7bc875d9. Report an issue: GitHub.