apache/beam · error · FileNotFoundException
The specified file does not exist
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.
Solutions
- Verify the gs:// path exists: gsutil ls <path> or storage.get via console.
- Check the file path/template configuration for typos or stale values.
- Guard with gcsUtil.expand/gcsUtil.treeList over a directory pattern before calling fileSize/getBlob.
- 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
- Resolve file paths from fresh directory listings instead of stale cached values
- Validate templated path options before pipeline start
- Use expand()/match() on globs rather than calling fileSize on possibly-absent exact paths
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
- Could not find file
- Error completing file copies with retries, sample: from
- Error trying to delete
- Error when reading
- File spec not found
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/766bea8a7bc875d9.
Report an issue: GitHub.
Appendix: 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)