argoproj/argo-workflows · error

Failed to set artifact key: %v

Error message

Failed to set artifact key: %v

What it means

After building the new storage key (uploads/<namespace>/<uuid>/<filename>), the server calls outputArtifact.SetKey(newKey). SetKey only supports keys for artifact location types that have a key concept (s3, oss, gcs, etc.); for unsupported location types it returns an error, surfaced as HTTP 500. This indicates the resolved artifact location type cannot hold the generated key.

Source

Thrown at server/artifacts/artifact_server.go:248

	originalKey, _ := artifactCopy.GetKey()
	// Sanitize filename to prevent path traversal attacks. path.Base only
	// recognises '/' as a separator, so normalise Windows-style '\' first.
	sanitizedFilename := path.Base(strings.ReplaceAll(header.Filename, "\\", "/"))
	if sanitizedFilename == "." || sanitizedFilename == "/" || sanitizedFilename == "" {
		http.Error(w, "Invalid filename", http.StatusBadRequest)
		return
	}
	// Replace the key with uploaded file path under uploads/
	newKey := fmt.Sprintf("uploads/%s/%s/%s", namespace, uploadUUID, sanitizedFilename)
	if validateErr := sutils.ValidateUploadedArtifactKey(namespace, newKey); validateErr != nil {
		a.serverInternalError(ctx, fmt.Errorf("generated artifact key failed self-validation: %w", validateErr), w)
		return
	}

	// Create a copy of the artifact for uploading (using artifactCopy which has resolved location)
	outputArtifact := artifactCopy.DeepCopy()
	if setErr := outputArtifact.SetKey(newKey); setErr != nil {
		http.Error(w, fmt.Sprintf("Failed to set artifact key: %v", setErr), http.StatusInternalServerError)
		return
	}

	a.logger.WithFields(logging.Fields{
		"originalKey": originalKey,
		"newKey":      newKey,
	}).Info(ctx, "Uploading artifact with new key")

	// Get the driver for the artifact
	kubeClient := auth.GetKubeClient(ctx)
	driver, err := a.artDriverFactory(ctx, outputArtifact, resources{kubeClient, namespace})
	if err != nil {
		http.Error(w, fmt.Sprintf("Failed to create artifact driver: %v", err), http.StatusInternalServerError)
		return
	}

	// Upload using SaveStream
	if err := driver.SaveStream(ctx, file, outputArtifact); err != nil {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Check the resolved artifact location type; use s3/gcs/azure/oss which support keys.
  2. Inspect the full error (%v of SetKey) in the response to identify the unsupported type.
  3. Fix the artifact definition or default artifact repository so it points at a key-capable backend.
  4. If it persists with a valid configuration, file a bug with the artifact YAML and Argo version.
Defensive patterns

Strategy: validation

Validate before calling

# Only key-capable backends support upload keys
kubectl -n $NS get workflowtemplate $TPL -o jsonpath='{range .spec.arguments.artifacts[*]}{.name}{": "}{.s3}{.gcs}{.azure}{.oss}{"\n"}{end}'

Type guard

function hasKeyCapableLocation(artifact) {
  return Boolean(artifact.s3 || artifact.gcs || artifact.azure || artifact.oss);
}

Try / catch

catch (e) {
  if (e.status === 500 && e.body.includes('Failed to set artifact key')) {
    log.error('resolved artifact location type cannot hold an upload key; fix artifact repository config', e);
  }
}

Prevention

When it happens

Trigger: The resolved artifact location is of a type without key support (e.g. some http/raw-derived or misconfigured location); a custom/default artifact repository resolution produced a location type SetKey does not handle; a bug or unusual artifact configuration where ArtifactLocation has a backend that lacks a Key field.

Common situations: Default artifact repository configured with a backend whose location type doesn't accept keys; artifact fields combining incompatible location blocks; upgrades where new location types were added but the upload path wasn't updated.

Related errors


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