argoproj/argo-workflows · error
artifact %s failed to load: %w
Error message
artifact %s failed to load: %w
What it means
After creating the temp dir, the executor calls artDriver.Load to fetch the artifact into the temp path. Any non-recoverable driver error is wrapped as 'artifact <name> failed to load: <cause>'. Optional artifacts whose error is CodeNotFound are silently skipped instead.
Source
Thrown at workflow/executor/executor.go:338
// The artifact is downloaded to a temporary location, after which we determine if
// the file is a tarball or not. If it is, it is first extracted then renamed to
// the desired location. If not, it is simply renamed to the location.
tempArtPath := artPath + ".tmp"
// Ensure parent directory exist, create if missing
tempArtDir := filepath.Dir(tempArtPath)
if mkdirErr := os.MkdirAll(tempArtDir, 0o700); mkdirErr != nil {
return fmt.Errorf("failed to create artifact temporary parent directory %s: %w", tempArtDir, mkdirErr)
}
ctx, span := we.Tracing.StartLoadArtifact(ctx, artPath)
defer span.End()
err = artDriver.Load(ctx, driverArt, tempArtPath)
if err != nil {
if art.Optional && argoerrs.IsCode(argoerrs.CodeNotFound, err) {
logger.WithField("name", art.Name).Info(ctx, "Skipping optional input artifact that was not found")
return nil
}
return fmt.Errorf("artifact %s failed to load: %w", art.Name, err)
}
err = we.unarchiveArtifact(ctx, art, tempArtPath, artPath)
if err != nil {
return err
}
logger.WithField("path", artPath).Info(ctx, "Successfully download file")
if art.Mode != nil {
err = chmod(artPath, *art.Mode, art.RecurseMode)
if err != nil {
return err
}
} else if driverArt.Plugin != nil {
// For plugin artifacts without explicit mode, ensure the file is writable
// by setting mode to 0666 so the main container can read/write it
err = chmod(artPath, 0666, art.RecurseMode)
if err != nil {View on GitHub (pinned to 35bff19146)
Solutions
- Read the wrapped cause to identify the driver-level failure (404, auth, network)
- Mark the artifact optional: true if the producer may legitimately skip it
- Verify the artifact's bucket/key and the artifact-repository credentials/secret
- Check pod network egress and the storage backend's availability
Example fix
# before
artifacts:
- name: maybe-data
path: /mnt/data
s3:
key: outputs/maybe.json
# after
artifacts:
- name: maybe-data
path: /mnt/data
optional: true
s3:
key: outputs/maybe.json Defensive patterns
Strategy: validation
Validate before calling
# Verify the object exists and credentials work before running: # aws s3 ls s3://my-bucket/outputs/maybe.json --region <region> # Mark artifacts optional when the producer may skip them: # artifacts: # - name: maybe-data # optional: true
Try / catch
if err := loadArtifacts(ctx); err != nil {
if strings.Contains(err.Error(), "failed to load") {
// inspect wrapped cause: 404 -> mark optional or fix key;
// 401/403 -> fix credentials; timeout -> retry
}
} Prevention
- Mark artifacts optional: true when upstream output is not guaranteed
- Verify bucket/key, region and credentials in the artifact repository config
- Check pod network egress to the storage backend
- Confirm the upstream step actually produced and archived the output
When it happens
Trigger: The storage driver (s3/gcs/azure/oss/http/git/raw/...) fails to download the artifact: object does not exist (and artifact not optional), bad credentials, network failure, wrong bucket/key, or a driver misconfiguration.
Common situations: Upstream step did not produce the output artifact but it isn't marked optional; expired/missing storage credentials; key renamed or bucket region wrong; network egress blocked from the pod; artifact deleted by retention policy.
Related errors
- failed to put file: %w
- Failed to save artifact: %v
- Artifact driver connection validation failed: %v
- failed to stream artifact: %v
- error getting key for artifact: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/6504315fef6137c4.
Report an issue: GitHub.