{"record":{"id":"dcb646af7e643a16","repo":"apache/beam","slug":"dynamic-wrapped-storageexception-via","errorCode":null,"errorMessage":"dynamic: wrapped StorageException via translateStorageException (AccessDeniedException on 403, FileNotFoundException on 404, FileAlreadyExistsException on 409, else IOException)","messagePattern":"dynamic: wrapped StorageException via translateStorageException \\(AccessDeniedException on 403, FileNotFoundException on 404, FileAlreadyExistsException on 409, else IOException\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV2.java","lineNumber":134,"sourceCode":"        return new IOException(e);\n    }\n  }\n\n  private IOException translateStorageException(\n      String bucketName, @Nullable String blobName, StorageException e) {\n    return translateStorageException(GcsPath.fromComponents(bucketName, blobName), e);\n  }\n\n  public Blob getBlob(GcsPath gcsPath, BlobGetOption... options) throws IOException {\n    try {\n      Blob blob = storage.get(gcsPath.getBucket(), gcsPath.getObject(), options);\n      if (blob == null) {\n        throw new FileNotFoundException(\n            String.format(\"The specified file does not exist: %s\", gcsPath.toString()));\n      }\n      return blob;\n    } catch (StorageException e) {\n      throw translateStorageException(gcsPath, e);\n    }\n  }\n\n  public long fileSize(GcsPath gcsPath) throws IOException {\n    return getBlob(gcsPath, BlobGetOption.fields(BlobField.SIZE)).getSize();\n  }\n\n  /** A class that holds either a {@link Blob} or an {@link IOException}. */\n  @AutoValue\n  public abstract static class BlobResult {\n\n    /** Returns the {@link Blob}. */\n    public abstract @Nullable Blob blob();\n\n    /** Returns the {@link IOException}. */\n    public abstract @Nullable IOException ioException();\n\n    @VisibleForTesting","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV2.java#L116-L152","documentation":"GcsUtilV2.getBlob fetches a GCS blob via the Storage client; a null blob is reported as FileNotFoundException, and any StorageException is translated by translateStorageException into AccessDeniedException (403), FileNotFoundException (404), FileAlreadyExistsException (409), or a generic IOException. This normalizes GCS API errors into standard java.nio.file exceptions.","triggerScenarios":"Calling fileSize(gcsPath), blob(gcsPath,...), or expand over a GcsPath where the object does not exist, the credential lacks storage.objects.get, or the Storage client raises an error (quota, server error).","commonSituations":"Typo'd gs:// path or missing object; service account missing Storage Object Viewer role; bucket in another project/network blocked; transient 5xx surfaced as IOException.","solutions":["Verify the gs:// path/object exists with gsutil ls.","Grant the caller's service account storage.objects.get (roles/storage.objectViewer).","Catch the specific nio exceptions (FileNotFoundException vs AccessDeniedException) and act accordingly; retry IOException for transient 5xx.","Check bucket location/firewall/VPC-SC boundaries if requests are blocked."],"exampleFix":"// before\nlong size = gcsUtil.fileSize(GcsPath.fromUri(path)); // throws raw\n// after\ntry {\n  long size = gcsUtil.fileSize(GcsPath.fromUri(path));\n} catch (FileNotFoundException e) {\n  // skip missing input\n} catch (AccessDeniedException e) {\n  // fix IAM / credentials\n}","handlingStrategy":"try-catch","validationCode":"// pre-check existence and permission\ntry {\n  gcsUtil.fileSize(gcsPath);\n} catch (FileNotFoundException e) { /* handle missing */ }\ncatch (AccessDeniedException e) { /* fix IAM before pipeline run */ }","typeGuard":null,"tryCatchPattern":"try {\n  Blob b = gcsUtil.blob(gcsPath);\n} catch (FileNotFoundException e) {\n  // object missing: skip or fail fast\n} catch (AccessDeniedException e) {\n  // IAM problem: alert operator\n} catch (IOException e) {\n  // transient: retry with backoff\n}","preventionTips":["Validate gs:// paths and object existence before pipeline submission.","Grant least-privilege objectViewer IAM to the worker service account.","Add retries around transient IOExceptions."],"tags":["gcs","java","io","storage","permission"],"backgroundTag":"resource-not-found","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}