argoproj/argo-workflows · error
unable to list files in %s: %w
Error message
unable to list files in %s: %w
What it means
When Delete determines the artifact is a directory prefix, it enumerates all blobs under the prefix with ListObjects before deleting them one by one. If that listing fails, Delete aborts with this error rather than partially deleting the directory.
Source
Thrown at workflow/artifacts/azure/azure.go:379
WithField("container", artifact.Azure.Container).
WithField("blob", artifact.Azure.Blob).
Info(ctx, "Deleting object from Azure Blob Storage")
containerClient, err := azblobDriver.newAzureContainerClient(ctx)
if err != nil {
return fmt.Errorf("unable to create Azure Blob Container client: %w", err)
}
isDir, err := azblobDriver.IsDirectory(ctx, artifact)
if err != nil {
return fmt.Errorf("unable to test if %s is a directory: %w", artifact.Azure.Blob, err)
}
if !isDir {
return DeleteBlob(ctx, containerClient, artifact.Azure.Blob, true)
}
files, err := azblobDriver.ListObjects(ctx, artifact)
if err != nil {
return fmt.Errorf("unable to list files in %s: %w", artifact.Azure.Blob, err)
}
directoryFile := ""
for _, file := range files {
if file == artifact.Azure.Blob {
directoryFile = file
continue
}
if err := DeleteBlob(ctx, containerClient, file, true); err != nil {
return err
}
}
if directoryFile != "" {
return DeleteBlob(ctx, containerClient, directoryFile, true)
}
return nil
}
View on GitHub (pinned to 35bff19146)
Solutions
- Check the wrapped error for auth (403) vs network causes.
- Verify the container exists and credentials have 'Storage Blob Data Reader' role for listing.
- Retry the delete; nothing has been deleted yet since listing precedes deletion.
- If the prefix is huge and timing out, delete blobs in smaller prefix batches with az CLI or Azure Storage Explorer.
- Ensure stable connectivity to the storage endpoint (no aggressive middlebox timeouts).
Defensive patterns
Strategy: retry
Validate before calling
// confirm the directory prefix is listable first
files, err := driver.ListObjects(ctx, artifact)
if err != nil {
return fmt.Errorf("cannot enumerate prefix %s before delete: %w", artifact.Azure.Blob, err)
} Try / catch
err := driver.Delete(ctx, artifact)
if err != nil && strings.Contains(err.Error(), "unable to list files") {
// safe to retry: listing precedes deletion, nothing was deleted
err = retry.Do(ctx, func() error { return driver.Delete(ctx, artifact) })
} Prevention
- Grant list permission (Storage Blob Data Reader / SAS 'l') on the container.
- Keep directory prefixes modest in blob count to avoid long listings.
- Handle transient 5xx with exponential backoff at the caller.
When it happens
Trigger: Delete on a directory-style artifact (prefix with blobs beneath it) where the ListBlobsFlat pager fails: auth rejection, network failure, container not found, or the client could not be created.
Common situations: Very large prefixes timing out through proxies; container deleted between IsDirectory and ListObjects; expired SAS token mid-operation; firewall rules blocking the data-plane listing.
Related errors
- unable to test if %s is a directory: %w
- unable to download blob %s: %w
- unable to open stream for blob %s: %w
- unable to upload stream to Azure blob %s: %w
- error listing blobs %s in Azure Blob Storage container: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/28847534daa5dcbc.
Report an issue: GitHub.