apache/druid · error · IOException
Failed to fetch google cloud storage object from bucket [%s]
Error message
Failed to fetch google cloud storage object from bucket [%s] and prefix [%s].
What it means
GoogleStorage.list() performs a paged blob listing for a bucket+prefix. Although GCS list calls normally return an empty page instead of null, Druid defensively throws this IOException when the SDK returns a null Page, so callers never dereference a missing result. It indicates the listing request failed rather than 'no results'.
Source
Thrown at extensions-core/google-extensions/src/main/java/org/apache/druid/storage/google/GoogleStorage.java:271
{
List<Storage.BlobListOption> options = new ArrayList<>();
if (prefix != null) {
options.add(Storage.BlobListOption.prefix(prefix));
}
if (pageSize != null) {
options.add(Storage.BlobListOption.pageSize(pageSize));
}
if (pageToken != null) {
options.add(Storage.BlobListOption.pageToken(pageToken));
}
Page<Blob> blobPage = storage.get().list(bucket, options.toArray(new Storage.BlobListOption[0]));
if (blobPage == null) {
throw new IOE("Failed to fetch google cloud storage object from bucket [%s] and prefix [%s].", bucket, prefix);
}
List<GoogleStorageObjectMetadata> googleStorageObjectMetadataList =
blobPage.streamValues()
.map(blob -> new GoogleStorageObjectMetadata(
blob.getBucket(),
blob.getName(),
blob.getSize(),
blob.getUpdateTimeOffsetDateTime()
.toEpochSecond() * 1000
))
.collect(Collectors.toList());
return new GoogleStorageObjectPage(googleStorageObjectMetadataList, blobPage.getNextPageToken());
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Retry the list call; null pages are usually transient client failures.
- Validate the bucket name against the project (gsutil ls or console) before listing.
- Catch IOException and fall back to an empty metadata list if 'no objects' is an acceptable outcome.
- Upgrade/inspect the google-cloud-storage client version if null pages recur with healthy buckets.
- Enable client logging to distinguish auth vs transport causes.
Example fix
// before
List<GoogleStorageObjectMetadata> objs = googleStorage.list(bucket, prefix, limit);
// after
List<GoogleStorageObjectMetadata> objs;
try {
objs = googleStorage.list(bucket, prefix, limit);
} catch (IOException e) {
log.warn("GCS list failed for gs://%s/%s, treating as empty", bucket, prefix, e);
objs = Collections.emptyList();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (bucket == null || bucket.isEmpty() || prefix == null) {
throw new IllegalArgumentException("bucket and prefix required before GCS list");
} Try / catch
try { page = googleStorage.list(bucket, prefix, limit); }
catch (IOException e) { page = Collections.emptyList(); /* or retry */ } Prevention
- Retry transient list failures with backoff.
- Validate bucket names against the project at startup.
- Monitor GCS client errors; upgrade the google-cloud-storage library if null pages recur.
- Use test mocks that mirror SDK behavior (empty page, not null).
When it happens
Trigger: Calling GoogleStorage.list(bucket, prefix, maxResults) when the Storage client returns a null Page — typically due to a client/transport problem, an invalid bucket argument, or a mocked/failed response in tests.
Common situations: Misspelled or renamed bucket in task-log/output config; transient GCS client failures; unit tests (expectListObjectsPageRequest) simulating null pages; network interruptions mid-list.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
- Failed to fetch google cloud storage object from bucket [%s]
- Failed to stream logs from: %s
- Input stream is null
- Invalid input file path [%s]
- Couldn't kill segment[%s]: [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/6d67f6f6c063d066.
Report an issue: GitHub.