argoproj/argo-workflows · error
failed to load artifact '%s': %w
Error message
failed to load artifact '%s': %w
What it means
loadArtifact converts a workflow artifact spec into a driver artifact via newDriverArt before handing it to the storage driver. If that conversion fails (e.g. the artifact's config/secret cannot be resolved), the error is wrapped as 'failed to load artifact <name>: <cause>'.
Source
Thrown at workflow/executor/executor.go:285
func (we *WorkflowExecutor) loadArtifact(ctx context.Context, pluginName wfv1.ArtifactPluginName, art wfv1.Artifact) error {
logger := logging.RequireLoggerFromContext(ctx)
logger.WithField("name", art.Name).Info(ctx, "Downloading artifact")
if !art.HasLocationOrKey() {
if art.Optional {
logger.WithField("name", art.Name).Info(ctx, "Ignoring optional artifact which was not supplied")
return nil
}
return argoerrs.Errorf(argoerrs.CodeNotFound, "required artifact '%s' not supplied", art.Name)
}
err := art.CleanPath()
if err != nil {
return err
}
driverArt, err := we.newDriverArt(&art)
if err != nil {
return fmt.Errorf("failed to load artifact '%s': %w", art.Name, err)
}
switch pluginName {
// If no plugin is specified only load non-plugin artifacts
case "":
if driverArt.Plugin != nil {
logger.Info(ctx, "Skipping artifact that is from a plugin")
return nil
}
// If a plugin is specified only load artifacts from that plugin
default:
if driverArt.Plugin == nil || driverArt.Plugin.Name != pluginName {
logger.WithFields(logging.Fields{"name": driverArt.Name, "plugin": driverArt.Plugin}).Info(ctx, "Skipping artifact that is not from the specified plugin")
return nil
}
}
artDriver, err := we.InitDriver(ctx, driverArt)
if err != nil {View on GitHub (pinned to 35bff19146)
Solutions
- Inspect the wrapped cause: usually a missing secret — create the referenced secret in the workflow namespace
- Verify the artifact repository configuration (default configs in the controller configmap) and credentials
- If the artifact comes from a plugin, confirm that plugin is loaded by the executor
- Use `argo lint` and check that the artifact name/spec in the template matches the artifact repository schema
Example fix
# before (artifact references missing secret)
artifacts:
- name: data
s3:
key: my/key
accessKeySecret:
name: s3-creds # does not exist
# after
artifacts:
- name: data
s3:
key: my/key
accessKeySecret:
name: s3-creds
key: accessKey # secret created in namespace Defensive patterns
Strategy: validation
Validate before calling
# Ensure referenced secrets exist before submitting: # kubectl get secret s3-creds -n <namespace> # and validate the workflow: # argo lint workflow.yaml
Try / catch
if err := loadArtifacts(ctx); err != nil {
if strings.Contains(err.Error(), "failed to load artifact") {
// check wrapped cause: missing secret vs invalid spec
}
} Prevention
- Create all storage secrets (accessKeySecret/secretKeySecret) in the workflow namespace before submit
- Validate the artifact repository configuration in the controller configmap
- Confirm plugin-sourced artifacts have their plugin loaded
- Lint workflows (`argo lint`) to catch malformed artifact specs
When it happens
Trigger: newDriverArt fails while resolving the artifact — typically a missing/misreferenced storage secret (s3/gcs/azure accessKey/secretKey), an invalid artifact spec, or an artifact-sources plugin lookup failure.
Common situations: Input artifact referencing a secretKeyRef that doesn't exist in the namespace; S3 bucket misconfigured in the artifact repository config; artifact defined with a plugin source but no plugin loaded; typo'd bucket/endpoint config.
Related errors
- artifact storage is not configured; see the docs for setup i
- template artifact location not set
- unsupported artifact driver
- failed to create artifact temporary parent directory %s: %w
- artifact %s failed to load: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/0aa845f019a21941.
Report an issue: GitHub.