argoproj/argo-workflows · error
unable to list blob %s in Azure Storage: %w
Error message
unable to list blob %s in Azure Storage: %w
What it means
DownloadDirectory lists all blobs under the artifact's blob prefix via ListObjects before downloading them. This error wraps a failure from that listing — either the container client creation inside ListObjects or a pager.NextPage API failure. The real cause is in the wrapped error.
Source
Thrown at workflow/artifacts/azure/azure.go:204
logger.WithFatal().WithError(closeErr).Warn(ctx, "unable to close file")
}
}()
_, err = blobClient.DownloadFile(ctx, outFile, nil)
return err
}
// DownloadDirectory downloads all of the files starting with the named blob prefix into a local directory.
func (azblobDriver *ArtifactDriver) DownloadDirectory(ctx context.Context, containerClient *container.Client, artifact *wfv1.Artifact, path string) error {
logger := logging.RequireLoggerFromContext(ctx)
logger.WithField("endpoint", artifact.Azure.Endpoint).
WithField("container", artifact.Azure.Container).
WithField("blob", artifact.Azure.Blob).
Info(ctx, "Downloading directory from Azure Blob Storage")
files, err := azblobDriver.ListObjects(ctx, artifact)
if err != nil {
return fmt.Errorf("unable to list blob %s in Azure Storage: %w", artifact.Azure.Blob, err)
}
err = os.MkdirAll(path, 0755)
if err != nil {
return fmt.Errorf("unable to create local directory %s: %w", path, err)
}
for _, file := range files {
// For ADLS Gen 2 accounts, we'll see a file whose name matches the directory. Skip it.
if file == artifact.Azure.Blob {
continue
}
relKeyPath := strings.TrimPrefix(file, artifact.Azure.Blob)
localPath := filepath.Join(path, relKeyPath)
err = DownloadFile(ctx, containerClient, file, localPath)
if err != nil {View on GitHub (pinned to 35bff19146)
Solutions
- Check the wrapped error code: 403 => grant List (Storage Blob Data Reader or SAS 'l' permission); 404 container => fix container name.
- Verify endpoint and credentials by running az storage blob list with the same key locally.
- If the wrapped error is a client-creation error, fix the endpoint/accountKey per the nested message.
- Retry on transient network/timeout errors; narrow the artifact prefix to reduce listing size.
- Ensure network egress from workflow pods to <account>.blob.core.windows.net:443 is allowed.
Example fix
// before permissions: r // after: SAS with list az storage blob generate-sas --permissions rl --https-only ...
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: list with the same prefix before running the workflow
_, err := containerClient.NewListBlobsFlatPager(&azblob.ListBlobsFlatOptions{Prefix: &prefix}).NextPage(ctx)
if err != nil { return fmt.Errorf("list precheck failed: %w", err) } Type guard
func isSasMissingListPerm(err error) bool {
var respErr *azcore.ResponseError
return errors.As(err, &respErr) && respErr.ErrorCode == "AuthorizationFailure"
} Try / catch
err := driver.Load(ctx, artifact, path)
if strings.Contains(err.Error(), "unable to list blob") {
var respErr *azcore.ResponseError
if errors.As(err, &respErr) {
if respErr.ErrorCode == "AuthorizationFailure" { /* add List permission */ }
if respErr.StatusCode >= 500 || respErr.StatusCode == 408 { /* retry */ }
}
} Prevention
- Generate SAS tokens with 'rl' permissions
- Verify container names with az CLI before submitting
- Allow egress to *.blob.core.windows.net:443
- Narrow artifact prefixes so listings stay small
When it happens
Trigger: ListObjects' list call fails: 403 AuthorizationFailure (SAS/identity lacks List), ContainerNotFound (wrong container name), InvalidQueryParameterValue/other REST errors, context deadline exceeded on huge prefixes, or newAzureContainerClient fails (bad endpoint/key).
Common situations: SAS token generated with only read ('r') but not list ('l') permission, typo in artifact.Azure.Container, storage account firewall blocking the cluster egress, listing a prefix with millions of blobs until timeout.
Related errors
- unable to determine if %s is a directory: %w
- unable to test if blob %s is a directory: %w
- unable to delete Azure Blob %s: %w
- error listing blobs %s in Azure Blob Storage container: %w
- unable to download blob %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/0a1c6917f6b476ac.
Report an issue: GitHub.