argoproj/argo-workflows · error
unable to open blob stream for %s: %w
Error message
unable to open blob stream for %s: %w
What it means
When the initial DownloadStream fails with BlobNotFound and the driver determines the blob is neither a directory nor an empty file, it re-reports the original BlobNotFound wrapped in this message. In practice this means the requested blob genuinely does not exist in the container.
Source
Thrown at workflow/artifacts/azure/azure.go:268
emptyFile = *response.ContentLength == 0
// We have a normal file blob, so just return the response body stream
if !emptyFile {
return response.Body, nil
}
} else if !bloberror.HasCode(origErr, bloberror.BlobNotFound) {
return nil, fmt.Errorf("unable to open stream for blob %s: %w", artifact.Azure.Blob, origErr)
}
isDir, err := azblobDriver.IsDirectory(ctx, artifact)
if err != nil {
return nil, fmt.Errorf("unable to test if blob %s is a directory: %w", artifact.Azure.Blob, err)
}
if isDir {
return nil, argoerrors.New(argoerrors.CodeNotImplemented, "Directory Stream capability currently unimplemented for Azure Blob")
} else if !emptyFile {
// Not a directory (and not successful retrieval of an empty file), so return
// the original BlobNotFound error
return nil, fmt.Errorf("unable to open blob stream for %s: %w", artifact.Azure.Blob, origErr)
}
return response.Body, nil
}
// Save saves an artifact to Azure Blob Storage
func (azblobDriver *ArtifactDriver) Save(ctx context.Context, path string, outputArtifact *wfv1.Artifact) error {
logger := logging.RequireLoggerFromContext(ctx)
logger.WithField("endpoint", outputArtifact.Azure.Endpoint).
WithField("container", outputArtifact.Azure.Container).
WithField("blob", outputArtifact.Azure.Blob).
Info(ctx, "Saving to Azure Blob Storage")
isDir, err := file.IsDirectory(path)
if err != nil {
return fmt.Errorf("failed to test if %s is a directory: %w", path, err)
}
View on GitHub (pinned to 35bff19146)
Solutions
- Verify the blob exists: az storage blob list --container-name <c> and compare exact names (case-sensitive).
- Check the producing workflow step actually completed and saved the artifact under that key.
- Add DAG/upstream dependencies so the consuming step runs after the artifact is saved.
- Confirm artifact 'path' (save location) and consumer 'key' match.
- Check you are pointing at the expected storage account/endpoint (production vs test).
Example fix
// before: consumer has no dependency on producer
tasks:
- name: consume
artifacts: [{name: out, from: "{{tasks.produce.outputs.artifacts.out}}"}]
// after: add dependency so artifact exists first
tasks:
- name: consume
depends: "produce"
... Defensive patterns
Strategy: validation
Validate before calling
iter := containerClient.NewListBlobsFlatPager(&azblob.ListBlobsFlatOptions{Prefix: &blob})
exists := false
for iter.More() {
page, err := iter.NextPage(ctx)
if err != nil { return err }
for _, b := range page.Segment.BlobItems {
if *b.Name == blob { exists = true }
}
}
if !exists { return fmt.Errorf("blob %s does not exist yet", blob) } Type guard
func isBlobNotFound(err error) bool {
return bloberror.HasCode(err, bloberror.BlobNotFound)
} Try / catch
stream, err := driver.OpenStream(ctx, artifact)
if err != nil {
if isBlobNotFound(errors.Unwrap(err)) {
// producer hasn't finished or key wrong — check workflow deps
}
return err
} Prevention
- Always declare DAG/task dependencies so consumers run after producers.
- Use artifact `from:` expressions instead of hand-typed keys.
- Avoid setting `optional: false` artifacts unless the producer is guaranteed.
- Lint workflows before submit to catch path typos.
When it happens
Trigger: OpenStream where the blob key is wrong, the upstream step never produced/saved the artifact, or the artifact was uploaded under a different prefix/container.
Common situations: Typo in artifact path; consumer workflow runs before producer saved the artifact (missing depends/dag dependency); archived artifact deleted; account/container mismatch.
Related errors
- unable to open stream for blob %s: %w
- unable to test if blob %s is a directory: %w
- unable to upload directory %s to Azure: %w
- unable to upload file %s to Azure: %w
- CodeNotFound
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/a06c70b1f14a2780.
Report an issue: GitHub.