apache/beam · error · IOException
GcsUtil V2 not initialized.
Error message
GcsUtil V2 not initialized.
What it means
GcsUtil delegates Blob-API (GCS JSON API v2) calls to delegateV2. getBlob throws IOException('GcsUtil V2 not initialized.') when the v2 delegate was never constructed — i.e. the GcsUtil was built via the legacy path without GCS v2 storage support enabled.
Solutions
- Use the legacy GcsUtil.object()/objectMetadata() methods which do not require the v2 delegate
- Initialize GcsUtil with the v2 delegate (enable GCS v2 storage support in options) before calling getBlob
- Check Beam version requirements/flags for GoogleCloudOptions experimental GCS v2 support
- If mocking in tests, also stub the v2 delegate or avoid exercising getBlob
Example fix
// before Blob blob = gcsUtil.getBlob(gcsPath); // after GcsUtil.GcsUtilFactory factory = new GcsUtil.GcsUtilFactory(); GcsUtil gcsUtil = factory.create(pipelineOptions); // initializes v2 delegate Blob blob = gcsUtil.getBlob(gcsPath);
Defensive patterns
Strategy: try-catch
Validate before calling
// check availability before calling
try { gcsUtil.getBlob(gcsPath); } catch (IOException e) { /* handle not-initialized vs real IO error */ } Try / catch
try { Blob b = gcsUtil.getBlob(gcsPath); }
catch (IOException e) {
if ("GcsUtil V2 not initialized.".equals(e.getMessage())) {
throw new IllegalStateException("Rebuild GcsUtil via GcsUtilFactory with v2 support", e);
}
throw e;
} Prevention
- Construct GcsUtil through GcsUtil.GcsUtilFactory, not the legacy no-arg/mock constructor
- Prefer legacy object()/objectMetadata() methods when v2 support is not needed
- Add a test asserting v2-dependent paths use a factory-built GcsUtil
When it happens
Trigger: Calling gcsUtil.getBlob(gcsPath, options) on a GcsUtil instance whose delegateV2 is null (constructed in legacy/test mode without v2 initialization).
Common situations: Tests constructing GcsUtil with a mocked legacy GcsUtil object; older integration paths that never call the v2 initializer; code using getBlob directly instead of the legacy object()/objectMetadata() methods.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- BigQuery temp location expected a valid 'gs://' path, but…
- BigQuery temp location expected a valid 'gs://' path, but…
- Can't get filename from root path in the bucket
- Can't resolve the sibling of a root path
- Could not find file
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/c38977794b103546.
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/GcsUtil.java:139
if (delegateV2 != null) {
return delegateV2.fileSize(path);
}
return delegate.fileSize(path);
}
/**
* @deprecated use {@link #getBlob(GcsPath, BlobGetOption...)}.
*/
@Deprecated
public StorageObject getObject(GcsPath gcsPath) throws IOException {
return delegate.getObject(gcsPath);
}
public Blob getBlob(GcsPath gcsPath, BlobGetOption... options) throws IOException {
if (delegateV2 != null) {
return delegateV2.getBlob(gcsPath, options);
}
throw new IOException("GcsUtil V2 not initialized.");
}
/**
* @deprecated use {@link #getBlobs(Iterable, BlobGetOption...)}.
*/
@Deprecated
public List<StorageObjectOrIOException> getObjects(List<GcsPath> gcsPaths) throws IOException {
List<GcsUtilV1.StorageObjectOrIOException> legacy = delegate.getObjects(gcsPaths);
return legacy.stream()
.map(StorageObjectOrIOException::fromLegacy)
.collect(java.util.stream.Collectors.toList());
}
public List<BlobResult> getBlobs(Iterable<GcsPath> gcsPaths, BlobGetOption... options)
throws IOException {
if (delegateV2 != null) {
return delegateV2.getBlobs(gcsPaths, options);
}View on GitHub (pinned to 12126d8942)