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

  1. Inspect the wrapped cause: usually a missing secret — create the referenced secret in the workflow namespace
  2. Verify the artifact repository configuration (default configs in the controller configmap) and credentials
  3. If the artifact comes from a plugin, confirm that plugin is loaded by the executor
  4. 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

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


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/0aa845f019a21941. Report an issue: GitHub.