apache/druid · error · RE
Failed to get blob item from Azure container[%s], prefix[%s
Error message
Failed to get blob item from Azure container[%s], prefix[%s]. Error: %s
What it means
This error wraps any exception thrown while listing blobs from Azure Blob Storage for a given container and prefix. AzureCloudBlobIterator.fetchNextBatch calls the Azure SDK's listBlobsByHierarchy and, on any failure (network, auth, missing container), rethrows as a RuntimeException (RE) with the container, prefix, and underlying message.
Source
Thrown at extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureCloudBlobIterator.java:135
{
try {
log.debug(
"fetching up to %s resources in container '%s' with prefix '%s'",
maxListingLength,
currentContainer,
currentPrefix
);
// We don't need to iterate by page because the client handles this, it will fetch the next page when necessary.
blobItemIterator = storage.listBlobsWithPrefixInContainerSegmented(
currentStorageAccount,
currentContainer,
currentPrefix,
maxListingLength,
config.getMaxTries()
).stream().iterator();
}
catch (Exception e) {
throw new RE(
e,
"Failed to get blob item from Azure container[%s], prefix[%s]. Error: %s",
currentContainer,
currentPrefix,
e.getMessage()
);
}
}
/**
* Advance objectSummaryIterator to the next non-placeholder, updating "currentObjectSummary".
*/
private void advanceBlobItem()
{
while (prefixesIterator.hasNext() || blobItemIterator.hasNext()) {
while (blobItemIterator.hasNext()) {
BlobItem blobItem = blobItemIterator.next();
if (!blobItem.isPrefix() && blobItem.getProperties().getContentLength() > 0) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the wrapped cause message (%s at the end) for the real Azure SDK error and fix accordingly
- Verify druid.azure.container, druid.azure.key/sharedAccessStorageToken in the runtime properties
- Confirm the container and prefix exist in the Azure portal / az CLI
- Retry the operation; increase druid.azure.maxTries if throttling is the cause
Example fix
// before iterator = azureStorage.listBlobs(currentContainer, currentPrefix, maxListingLength, 1); // after int maxTries = Math.max(config.getMaxTries(), 3); // tolerate transient listing failures
Defensive patterns
Strategy: retry
Validate before calling
if (config.getContainer() == null || config.getContainer().isEmpty()) throw new IllegalArgumentException("druid.azure.container must be set"); Try / catch
try { iterator.fetchNextBatch(); } catch (RE e) { log.error("Azure listing failed for container=%s prefix=%s: %s", container, prefix, e.getCause(), e); if (isTransient(e.getCause())) retry(); } Prevention
- Validate druid.azure.container/prefix at config load time
- Verify container existence with a cheap list call before deep-storage operations
- Configure reasonable maxTries with backoff for transient Azure errors
- Monitor Azure throttling (503) metrics
When it happens
Trigger: Calling AzureCloudBlobIterator.advanceBlobItem/fetchNextBatch when the Azure listBlobsByHierarchy call fails: invalid container name, wrong storage key/SAS token, transient network errors after exhausting config.getMaxTries(), or a nonexistent container.
Common situations: Misconfigured druid.azure.container or credentials; container deleted or renamed; Azure throttling/transient HTTP 500/503 during deep storage listing; network outage between Druid and Azure.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Recoverable exception
- RuntimeException wrapping underlying cause
- IOException wrapping underlying cause
- Failed to stream logs from: %s
- IOException wrapping underlying cause
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/867f5018d44acbe1.
Report an issue: GitHub.