{"record":{"id":"867f5018d44acbe1","repo":"apache/druid","slug":"failed-to-get-blob-item-from-azure-container-s","errorCode":null,"errorMessage":"Failed to get blob item  from Azure container[%s], prefix[%s]. Error: %s","messagePattern":"Failed to get blob item  from Azure container\\[(.+?)\\], prefix\\[(.+?)\\]\\. Error: (.+?)","errorType":"exception","errorClass":"RE","httpStatus":null,"severity":"error","filePath":"extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureCloudBlobIterator.java","lineNumber":135,"sourceCode":"  {\n    try {\n      log.debug(\n          \"fetching up to %s resources in container '%s' with prefix '%s'\",\n          maxListingLength,\n          currentContainer,\n          currentPrefix\n      );\n      // We don't need to iterate by page because the client handles this, it will fetch the next page when necessary.\n      blobItemIterator = storage.listBlobsWithPrefixInContainerSegmented(\n          currentStorageAccount,\n          currentContainer,\n          currentPrefix,\n          maxListingLength,\n          config.getMaxTries()\n      ).stream().iterator();\n    }\n    catch (Exception e) {\n      throw new RE(\n          e,\n          \"Failed to get blob item  from Azure container[%s], prefix[%s]. Error: %s\",\n          currentContainer,\n          currentPrefix,\n          e.getMessage()\n      );\n    }\n  }\n\n  /**\n   * Advance objectSummaryIterator to the next non-placeholder, updating \"currentObjectSummary\".\n   */\n  private void advanceBlobItem()\n  {\n    while (prefixesIterator.hasNext() || blobItemIterator.hasNext()) {\n      while (blobItemIterator.hasNext()) {\n        BlobItem blobItem = blobItemIterator.next();\n        if (!blobItem.isPrefix() && blobItem.getProperties().getContentLength() > 0) {","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureCloudBlobIterator.java#L117-L153","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\niterator = azureStorage.listBlobs(currentContainer, currentPrefix, maxListingLength, 1);\n// after\nint maxTries = Math.max(config.getMaxTries(), 3); // tolerate transient listing failures","handlingStrategy":"retry","validationCode":"if (config.getContainer() == null || config.getContainer().isEmpty()) throw new IllegalArgumentException(\"druid.azure.container must be set\");","typeGuard":null,"tryCatchPattern":"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(); }","preventionTips":["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"],"tags":["azure","blob-storage","listing","network"],"backgroundTag":"http-error-response","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}