argoproj/argo-workflows · error
failed to test if %s/%s is a directory: %w
Error message
failed to test if %s/%s is a directory: %w
What it means
After OSS returns NoSuchKey, Load checks whether the key is actually an OSS 'directory' via IsOssDirectory (a list-objects call under the prefix). If that directory probe itself errors (permissions on ListObjects, network failure), Load fails with 'failed to test if <bucket>/<key> is a directory'.
Source
Thrown at workflow/artifacts/oss/oss.go:161
return !isTransientOSSErr(ctx, err), err
}
objectName := inputArtifact.OSS.Key
dirPath := filepath.Dir(path)
err = os.MkdirAll(dirPath, 0o700)
if err != nil {
return false, fmt.Errorf("mkdir %s error: %w", dirPath, err)
}
origErr := bucket.GetObjectToFile(objectName, path)
if origErr == nil {
return true, nil
}
if !IsOssErrCode(origErr, "NoSuchKey") {
return !isTransientOSSErr(ctx, origErr), fmt.Errorf("failed to get file: %w", origErr)
}
// If we get here, the error was a NoSuchKey. The key might be a oss "directory"
isDir, err := IsOssDirectory(bucket, objectName)
if err != nil {
return !isTransientOSSErr(ctx, err), fmt.Errorf("failed to test if %s/%s is a directory: %w", bucketName, objectName, err)
}
if !isDir {
// It's neither a file, nor a directory. Return the original NoSuchKey error
return false, origErr
}
if err = GetOssDirectory(ctx, bucket, objectName, path); err != nil {
return !isTransientOSSErr(ctx, err), fmt.Errorf("failed get directory: %w", err)
}
return true, nil
})
return err
}
// OpenStream opens a stream reader for an artifact from OSS compliant storage
func (ossDriver *ArtifactDriver) OpenStream(ctx context.Context, inputArtifact *wfv1.Artifact) (io.ReadCloser, error) {
var stream io.ReadCloser
err := waitutil.Backoff(defaultRetry,View on GitHub (pinned to 35bff19146)
Solutions
- Grant the OSS credentials oss:ListObjects (ListBucket) permission on the bucket.
- If the artifact should be a file, check the exact key spelling — a wrong key triggers the NoSuchKey+probe path; fix the key to avoid the probe entirely.
- For intermittent causes, retry the workflow; isTransientOSSErr already filters retryable codes.
- Ensure the STS role policy includes both GetObject and ListBucket actions.
Example fix
// before (RAM policy)
{ "Statement": [{ "Action": ["oss:GetObject"], "Effect": "Allow" }] }
// after
{ "Statement": [{ "Action": ["oss:GetObject", "oss:ListObjects"], "Effect": "Allow" }] } Defensive patterns
Strategy: validation
Validate before calling
// ensure creds can list before workflows that may hit directory keys
cli, _ := oss.New(endpoint, ak, sk)
b, _ := cli.Bucket(bucket)
_, err := b.ListObjects(oss.Prefix(key), oss.MaxKeys(1))
if err != nil {
return fmt.Errorf("credentials lack ListObjects on %s: %w", bucket, err)
} Try / catch
err := driver.Load(ctx, art, path)
if err != nil && strings.Contains(err.Error(), "is a directory") {
// list-permission or transient failure during NoSuchKey probe; check RAM policy
} Prevention
- Include oss:ListObjects/ListBucket in RAM policies whenever directory-style keys are possible
- Use exact object keys instead of folder prefixes to skip the probe path entirely
- Retry transient failures — isTransientOSSErr already marks retryable codes
When it happens
Trigger: GetObjectToFile returns NoSuchKey and the follow-up IsOssDirectory(bucket, objectName) errors — most often the credentials lack oss:ListObjects permission on the bucket, or a transient network failure during the list call after retries.
Common situations: RAM policies that grant GetObject but not ListObjects (common with least-privilege setups); keys pointing to folder-style prefixes while the policy only allows reading specific objects; intermittent OSS connectivity with retry budget exhausted.
Related errors
- mkdir %s error: %w
- failed get directory: %w
- unable to test if blob %s is a directory: %w
- unable to open file %s: %w
- ListObjects is currently not supported for this artifact typ
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/e812feb4e897cb0a.
Report an issue: GitHub.