argoproj/argo-workflows · error
unable to determine if %s is a directory: %w
Error message
unable to determine if %s is a directory: %w
What it means
During Load, after a BlobNotFound (or empty ADLS Gen2 file), the driver calls IsDirectory, which lists blobs under the key's prefix. If that list call fails, the wrapped error is returned here. It hides the actual list failure (auth, container not found, network) behind the directory probe.
Source
Thrown at workflow/artifacts/azure/azure.go:147
fileInfo, lstatErr := os.Lstat(path)
if lstatErr != nil {
return fmt.Errorf("unable to retrieve stats for downloaded file %s: %w", path, lstatErr)
}
// Empty file means it could be an ADLS Gen 2 account and we downloaded the
// directory as an empty file -- we'll check below. If it's a non-empty file,
// then we successfully downloaded a file blob.
if fileInfo.Size() > 0 {
return nil
}
isEmptyFile = true
} else if !bloberror.HasCode(origErr, bloberror.BlobNotFound) {
return fmt.Errorf("unable to download blob %s: %w", artifact.Azure.Blob, origErr)
}
isDir, err := azblobDriver.IsDirectory(ctx, artifact)
if err != nil {
return fmt.Errorf("unable to determine if %s is a directory: %w", artifact.Azure.Blob, err)
}
// It's not a directory and the file doesn't exist, Return the original NoSuchKey error.
if !isDir && !isEmptyFile {
return argoerrors.New(argoerrors.CodeNotFound, origErr.Error())
}
// When we tried to download the blob as a file, we created an empty file for the
// blob as a target. We need to delete that empty file so we can re-create as a directory.
err = os.Remove(path)
if err != nil {
return fmt.Errorf("unable to remove attempted file download %s: %w", path, err)
}
// It's a directory, so download all of the files.
err = azblobDriver.DownloadDirectory(ctx, containerClient, artifact, path)
if err != nil {
return fmt.Errorf("unable to download directory %s: %w", artifact.Azure.Blob, err)View on GitHub (pinned to 35bff19146)
Solutions
- Inspect the wrapped error code: grant the credential Storage Blob Data Reader (includes List) if it's a 403.
- If using SAS, regenerate it with List ('l') permission included.
- Confirm the container name in the artifact is correct; a wrong container fails list operations.
- Retry the workflow on transient (network/timeout) wrapped errors.
- For ADLS Gen2, verify RBAC on the storage account allows directory listing, not just blob read.
Example fix
// before: SAS without list permission az storage blob generate-sas --permissions r ... // after: include list permission az storage blob generate-sas --permissions rl ...
Defensive patterns
Strategy: try-catch
Validate before calling
// verify list permission before relying on directory artifacts
pager := containerClient.NewListBlobsFlatOptions(&azblob.ListBlobsFlatOptions{Prefix: &prefix})
if _, err := pager.NextPage(ctx); err != nil { return err } Type guard
func isListAuthFailure(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 determine if") {
var respErr *azcore.ResponseError
if errors.As(err, &respErr) && respErr.ErrorCode == "AuthorizationFailure" {
// grant List permission (Storage Blob Data Reader or SAS 'l')
}
} Prevention
- Generate SAS tokens with both read and list permissions ('rl')
- Assign Storage Blob Data Reader role rather than raw key-only Read scoping
- Test directory artifacts with a list call before production
- Keep container names verified via az storage container list
When it happens
Trigger: DownloadFile returned BlobNotFound (or empty file) and then containerClient.NewListBlobsFlatPager/NextPage in IsDirectory fails: 403 AuthorizationFailure on list, ContainerNotFound, invalid SharedKey/SAS signature on list operations, transient network failure.
Common situations: SAS token lacking List permission (only Read), account key valid for get but firewall/rate limits hitting list calls, misconfigured endpoint so list goes to wrong account, HNS-enabled accounts with permission differences between read and list.
Related errors
- unable to list blob %s in Azure Storage: %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/a2a95086c0e388fb.
Report an issue: GitHub.