argoproj/argo-workflows · error

failed to Create WorkflowArtifactGCTask %q for Garbage Colle

Error message

failed to Create WorkflowArtifactGCTask %q for Garbage Collection: %w

What it means

createWorkflowArtifactGCTask creates a WorkflowArtifactGCTask custom resource via the Argo clientset when the informer cache says it doesn't exist. Any Create failure other than 'already exists handled upstream' is wrapped here at workflow/controller/artifact_gc.go:371 — typically RBAC denial, validation failure, or API-server issues.

Source

Thrown at workflow/controller/artifact_gc.go:371

	}
	return task.(*wfv1.WorkflowArtifactGCTask), nil
}

// create WorkflowArtifactGCTask CRD object
func (woc *wfOperationCtx) createWorkflowArtifactGCTask(ctx context.Context, task *wfv1.WorkflowArtifactGCTask) (*wfv1.WorkflowArtifactGCTask, error) {
	// first make sure it doesn't already exist
	foundTask, err := woc.getArtifactTask(task.Name)
	if err != nil {
		return nil, err
	}
	if foundTask != nil {
		woc.log.WithField("task", task.Name).Debug(ctx, "Artifact GC Task already exists")
	} else {
		woc.log.WithField("task", task.Name).Info(ctx, "Creating Artifact GC Task")

		task, err = woc.controller.wfclientset.ArgoprojV1alpha1().WorkflowArtifactGCTasks(woc.wf.Namespace).Create(ctx, task, metav1.CreateOptions{})
		if err != nil {
			return nil, fmt.Errorf("failed to Create WorkflowArtifactGCTask %q for Garbage Collection: %w", task.Name, err)
		}
	}
	return task, nil
}

// create the Pod which will do the deletions
func (woc *wfOperationCtx) createArtifactGCPod(ctx context.Context, strategy wfv1.ArtifactGCStrategy, tasks []*wfv1.WorkflowArtifactGCTask,
	info podInfo, podName string, templatesToArtList templatesToArtifacts, templatesByName map[string]*wfv1.Template) (*corev1.Pod, error) {
	woc.log.WithFields(logging.Fields{"strategy": strategy, "podName": podName}).Info(ctx, "creating pod to delete artifacts")

	// Pod is owned by WorkflowArtifactGCTasks, so it will die automatically when all of them have died
	ownerReferences := make([]metav1.OwnerReference, len(tasks))
	for i, task := range tasks {
		// make sure pod gets deleted with the WorkflowArtifactGCTasks
		ownerReferences[i] = *metav1.NewControllerRef(task, wfv1.SchemeGroupVersion.WithKind(workflow.WorkflowArtifactGCTaskKind))
	}

	artifactLocations := make([]*wfv1.ArtifactLocation, 0)

View on GitHub (pinned to 35bff19146)

Solutions

  1. Check the wrapped %w error in controller logs: if 403, grant the workflow-controller service account create on workflowartifactgctasks (check manifests/install.yaml RBAC for your version).
  2. If AlreadyExists, it's benign — the informer cache was stale; the next reconcile will pick up the existing task.
  3. If validation error, inspect the task payload (often CR size); reduce artifacts per workflow or upgrade to a version that splits tasks.
  4. Verify the namespace is Active and the WorkflowArtifactGCTask CRD is installed: kubectl get crd workflowartifactgctasks.argoproj.io.

Example fix

// before: controller RBAC lacks the CRD verb
// after: add to the workflow-controller ClusterRole
rules:
  - apiGroups: ["argoproj.io"]
    resources: ["workflowartifactgctasks"]
    verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check RBAC with kubectl auth
cmd := exec.Command("kubectl", "auth", "can-i", "create", "workflowartifactgctasks.argoproj.io",
    "-n", ns, "--as", "system:serviceaccount:argo:workflow-controller")

Type guard

apierr.IsAlreadyExists(err)  // benign stale-cache race; other statuses need action

Try / catch

if createErr != nil {
    if status := apierr.IsForbidden(createErr); status { /* fix controller RBAC */ }
    if apierr.IsAlreadyExists(createErr) { /* stale cache — safe to ignore */ }
}

Prevention

When it happens

Trigger: POST to /apis/argoproj.io/v1alpha1/.../workflowartifactgctasks fails: RBAC forbids the controller's service account; the CR is invalid (e.g. >1MB, bad ownerRef); the resource was created by another actor between cache check and Create (AlreadyExists); namespace is terminating; API server unreachable.

Common situations: Workflow-controller ClusterRole missing argoproj.io/workflowartifactgctasks create permission after manual RBAC tightening or partial upgrade; namespace stuck in Terminating; admission webhooks rejecting the object.

Related errors


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