argoproj/argo-workflows · error

could not save to config map cache: %w

Error message

could not save to config map cache: %w

What it means

save() persists a memoization entry into a ConfigMap; if the ConfigMap does not yet exist it is created via the Kubernetes API. When that Create call fails (RBAC denial, namespace issues, quota, API errors), the failure is wrapped as 'could not save to config map cache' and the memoized node is marked failed.

Source

Thrown at workflow/controller/cache/configmap_cache.go:173

		c.logError(ctx, err, logging.Fields{"key": key}, errString)
		return err
	}

	c.lock.Lock()
	defer c.lock.Unlock()

	c.logInfo(ctx, logging.Fields{"key": key, "nodeID": nodeID}, "Saving ConfigMap cache entry")

	cache, err := c.kubeClient.CoreV1().ConfigMaps(c.namespace).Get(ctx, c.name, metav1.GetOptions{})
	if apierr.IsNotFound(err) || cache == nil {
		cache, err = c.kubeClient.CoreV1().ConfigMaps(c.namespace).Create(ctx, &apiv1.ConfigMap{
			ObjectMeta: metav1.ObjectMeta{
				Name: c.name,
			},
		}, metav1.CreateOptions{})
		if err != nil {
			c.logError(ctx, err, logging.Fields{"key": key, "nodeID": nodeID}, "Error saving to ConfigMap cache")
			return fmt.Errorf("could not save to config map cache: %w", err)
		}
	} else {
		validateErr := c.validateConfigmap(ctx, cache)
		if validateErr != nil {
			return validateErr
		}
	}

	creationTime := time.Now()
	cache.SetLabels(map[string]string{common.LabelKeyConfigMapType: common.LabelValueTypeConfigMapCache})

	newEntry := Entry{
		NodeID:            nodeID,
		Outputs:           value,
		CreationTimestamp: metav1.Time{Time: creationTime},
		LastHitTimestamp:  metav1.Time{Time: creationTime},
	}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Check controller logs for the underlying error (logError 'Error saving to ConfigMap cache') to see the real Kubernetes cause.
  2. Verify RBAC: the workflow-controller service account needs create/update/get on configmaps in the workflow namespace (see the memoization docs RBAC snippet).
  3. Confirm the ConfigMap name/namespace from the memoize config and that no quota (resourcequota on configmap count) blocks creation.
  4. Re-run the workflow after fixing — memoization save failures are not retried automatically for the same node.
  5. If a name conflict race, retry — the next save will take the update path instead of create.

Example fix

# before: RBAC missing
# after: grant the controller SA access
kind: Role
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["create", "get", "update", "delete"]
# bind it to the workflow-controller service account in the workflow namespace
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check permissions before submitting memoized workflows
kubectl auth can-i create configmaps -n <workflow-ns> --as=system:serviceaccount:<argo-ns>:workflow-controller

Try / catch

err := cache.Save(ctx, key, nodeID, entry)
if err != nil {
  var serr *apierrors.StatusError
  if errors.As(err, &serr) && apierrors.IsForbidden(err) {
    // fix RBAC then re-run; memoization save is not auto-retried
  }
  return fmt.Errorf("memoization save failed: %w", err)
}

Prevention

When it happens

Trigger: First-ever save for a given memoization ConfigMap where CoreV1().ConfigMaps(ns).Create fails: service account lacks create permission on configmaps, namespace mismatch, resource quota exceeded, API server unreachable, or name/label conflicts.

Common situations: Memoization ConfigMap in a namespace where the controller's SA has no create rights (RBAC not synced after installing Argo); Kubernetes 1.22+ with stale manifests; air-gapped clusters with API latency; the ConfigMap was deleted mid-run causing a create/conflict race.

Related errors


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