argoproj/argo-workflows · error

Failed to get WorkflowTemplate %s/%s: %v

Error message

Failed to get WorkflowTemplate %s/%s: %v

What it means

The handler fetches the WorkflowTemplate with the caller's own k8s client (auth.GetWfClient) so the user's RBAC applies. If the GET fails (template missing, no permission, bad namespace), it returns 404 with a message including the error text. Note the instance-ID mismatch case is deliberately masked as a bare 404 to avoid leaking existence.

Source

Thrown at server/artifacts/artifact_server.go:136

	if !allowed {
		http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
		return
	}
	allowed, err = auth.CanI(ctx, "create", "workflows", namespace, "")
	if err != nil {
		a.serverInternalError(ctx, err, w)
		return
	}
	if !allowed {
		http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
		return
	}

	// Get WorkflowTemplate to find artifact configuration
	wfClient := auth.GetWfClient(ctx)
	wfTemplate, err := wfClient.ArgoprojV1alpha1().WorkflowTemplates(namespace).Get(ctx, workflowTemplateName, metav1.GetOptions{})
	if err != nil {
		http.Error(w, fmt.Sprintf("Failed to get WorkflowTemplate %s/%s: %v", namespace, workflowTemplateName, err), http.StatusNotFound)
		return
	}
	if validateErr := a.instanceIDService.Validate(wfTemplate); validateErr != nil {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	// Enforce a hard cap on the total request body size before buffering any
	// of it, so a caller cannot exhaust server disk/memory with an oversized upload.
	maxUploadBytes, err := env.GetInt("ARGO_SERVER_MAX_ARTIFACT_UPLOAD_BYTES", 1<<30)
	if err != nil {
		a.serverInternalError(ctx, err, w)
		return
	}
	r.Body = http.MaxBytesReader(w, r.Body, int64(maxUploadBytes))

	// mime/multipart.ReadForm already removes temp files on parse error, but
	// registering cleanup here makes the handler's correctness independent of

View on GitHub (pinned to 35bff19146)

Solutions

  1. Verify the template exists: kubectl get workflowtemplate <name> -n <namespace>
  2. Use the exact namespace from the template's location in the URL
  3. Check RBAC if the raw error says 'forbidden' — the caller needs workflowtemplates/get
  4. If using instanceID, confirm the template carries the expected workflow-controller instanceID label

Example fix

# before
curl -X POST -F 'file=@d.bin' .../upload-artifacts/prod/my-template/art
# after (template actually lives in argo namespace)
curl -X POST -F 'file=@d.bin' .../upload-artifacts/argo/my-template/art
Defensive patterns

Strategy: validation

Validate before calling

kubectl get workflowtemplate <name> -n <namespace> || \
  echo "template missing — fix name/namespace before uploading"

Prevention

When it happens

Trigger: WorkflowTemplate does not exist in the namespace; caller lacks 'get' on workflowtemplates (RBAC error surfaced as 404); typo in template name; controller-configured instanceID does not match the template's metadata (separate bare-404 path).

Common situations: Templates deployed to a different namespace than the upload URL; name typos; CRD not installed or argo namespace misconfigured; multi-tenant setups where instanceID labels differ.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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