argoproj/argo-workflows · error
error listing blobs %s in Azure Blob Storage container: %w
Error message
error listing blobs %s in Azure Blob Storage container: %w
What it means
ListObjects iterates the List Blobs Flat pager; any failure from pager.NextPage (non-2xx response, auth failure, network error) is wrapped as 'error listing blobs %s in Azure Blob Storage container'. Note only the first failing page aborts the loop.
Source
Thrown at workflow/artifacts/azure/azure.go:435
logger.WithField("endpoint", artifact.Azure.Endpoint).
WithField("container", artifact.Azure.Container).
WithField("blob", artifact.Azure.Blob).
Info(ctx, "Listing blobs in Azure Blob Storage")
containerClient, err := azblobDriver.newAzureContainerClient(ctx)
if err != nil {
return nil, fmt.Errorf("unable to create Azure Blob Container client: %w", err)
}
listOpts := azblob.ListBlobsFlatOptions{
Prefix: &artifact.Azure.Blob,
Marker: nil,
}
pager := containerClient.NewListBlobsFlatPager(&listOpts)
for pager.More() {
resp, err := pager.NextPage(ctx)
if err != nil {
return nil, fmt.Errorf("error listing blobs %s in Azure Blob Storage container: %w", artifact.Azure.Blob, err)
}
for _, v := range resp.Segment.BlobItems {
files = append(files, *v.Name)
}
}
return files, nil
}
// IsDirectory indicates whether or not the artifact represents a directory or a single file.
func (azblobDriver *ArtifactDriver) IsDirectory(ctx context.Context, artifact *wfv1.Artifact) (bool, error) {
blobPrefix := artifact.Azure.Blob
if blobPrefix == "" {
return true, nil
}
if !strings.HasSuffix(blobPrefix, "/") {
blobPrefix += "/"
}View on GitHub (pinned to 35bff19146)
Solutions
- Grant the credential 'Storage Blob Data Reader' role (or SAS with list permission) on the container.
- Verify the container name exists: az storage container list on the account.
- Check for 403 vs 404 vs 503 in the wrapped error and fix accordingly (permissions / name / throttling).
- If throttled, reduce listing pressure or retry with backoff; the SDK default retries may not be enough for sustained 503s.
- Confirm network path: test from the same pod with curl to https://<account>.blob.core.windows.net.
Defensive patterns
Strategy: retry
Validate before calling
// cheap pre-check that the container is listable
_, err := driver.ListObjects(ctx, &wfv1.Artifact{ArtifactLocation: wfv1.ArtifactLocation{
Azure: &wfv1.AzureArtifact{Endpoint: ep, Container: c, Blob: probePrefix}}})
if err != nil { return err } Try / catch
err := retry.Do(ctx, func() error {
files, err = driver.ListObjects(ctx, artifact)
var respErr *azcore.ResponseError
if err != nil && errors.As(err, &respErr) && respErr.StatusCode == 403 {
return retry.Fatal(err) // don't retry auth errors
}
return err
}) Prevention
- Assign Storage Blob Data Reader for listing operations.
- Use SAS tokens that include list ('l') permission.
- Back off on 503 throttling; don't hammer large prefixes.
- Monitor storage account availability metrics.
When it happens
Trigger: Listing blobs under an artifact prefix when Azure returns 403 (no list permission), 404 (container missing), throttling (503) beyond retries, or a connection reset/DNS failure mid-pagination.
Common situations: Identity has only Reader (control plane) but not 'Storage Blob Data Reader' (data plane); container typo; private endpoint/firewall blocking egress; SAS token lacking 'l' (list) permission; storage account throttling large prefix listings.
Related errors
- unable to determine if %s is a directory: %w
- unable to list blob %s in Azure Storage: %w
- unable to test if blob %s is a directory: %w
- unable to test if %s is a directory: %w
- unable to list files in %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/d49c509abf2f4294.
Report an issue: GitHub.