argoproj/argo-workflows · critical

no Node found by the name of %s; wf.Status.Nodes=%+v

Error message

no Node found by the name of %s;  wf.Status.Nodes=%+v

What it means

After executing (or observing) a template's node, executeTemplate re-reads the node from the workflow status by name with wf.GetNodeByName. If no node with that name exists in wf.Status.Nodes, it logs the error, marks the whole workflow as Error via markWorkflowError, and returns. This guards against reconciling against a node that has vanished from status.

Source

Thrown at workflow/controller/operator.go:2599

			if retryPolicy != wfv1.RetryPolicyAlways &&
				retryPolicy != wfv1.RetryPolicyOnError &&
				retryPolicy != wfv1.RetryPolicyOnTransientError {
				release = true
			}
		}
		if release {
			woc.controller.syncManager.Release(ctx, woc.wf, node.ID, processedTmpl.Synchronization)
			return node, err
		}
	}

	if node.Fulfilled() {
		woc.controller.syncManager.Release(ctx, woc.wf, node.ID, processedTmpl.Synchronization)
	}

	retrieveNode, retrieveErr := woc.wf.GetNodeByName(node.Name)
	if retrieveErr != nil {
		nodeErr := fmt.Errorf("no Node found by the name of %s;  wf.Status.Nodes=%+v", node.Name, woc.wf.Status.Nodes)
		woc.log.Error(ctx, nodeErr.Error())
		woc.markWorkflowError(ctx, nodeErr)
		return node, nodeErr
	}
	node = retrieveNode

	// Swap the node back to retry node
	if retryNodeName != "" {
		retryNode, getErr := woc.wf.GetNodeByName(retryNodeName)
		if getErr != nil {
			retryErr := fmt.Errorf("no Retry Node found by the name of %s;  wf.Status.Nodes=%+v", retryNodeName, woc.wf.Status.Nodes)
			woc.log.Error(ctx, retryErr.Error())
			woc.markWorkflowError(ctx, retryErr)
			return node, retryErr
		}

		if !retryNode.Phase.Fulfilled(retryNode.TaskResultSynced) && node.Phase.Fulfilled(node.TaskResultSynced) { // if the retry child has completed we need to update the parent's status
			retryNode, err = woc.executeTemplate(ctx, retryNodeName, orgTmpl, tmplCtx, args, opts)

View on GitHub (pinned to 35bff19146)

Solutions

  1. Dump wf.Status.Nodes (kubectl get wf <name> -o yaml) and search for the node name printed in the message to confirm it is missing.
  2. Retry the workflow (argo retry <name>) to rebuild node status from existing pods.
  3. If you hand-edited the Workflow object, restore the original or resubmit cleanly (argo resubmit).
  4. Verify controller and CRD versions match (manifests/install.yaml from the same release); mismatched CRDs can drop status fields.
  5. Check for node-status offloading/hydration issues in controller logs; upgrade Argo Workflows if a known bug applies.
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: confirm the node name exists in status before depending on it
wf, _ := wfClient.ArgoprojV1alpha1().Workflows(ns).Get(ctx, name, metav1.GetOptions{})
if wf.Status.Nodes.Find(func(n wfv1.NodeStatus) bool { return n.Name == nodeName }) == nil {
	return fmt.Errorf("node %q not in status; retry the workflow", nodeName)
}

Prevention

When it happens

Trigger: executeTemplate completes and calls woc.wf.GetNodeByName(node.Name); the node lookup fails because the node record was never persisted, was pruned/truncated from status, or the workflow object in memory diverges from expected state. Raised from any path into executeTemplate: executeDAGTask, runOnExitNode, workflow/template lifecycle hooks, operate().

Common situations: Extremely large workflows where node status was offloaded and hydration failed; manual kubectl edits removing nodes; controller restarts racing with stale workflow objects; version-mismatch between controller and CRDs after upgrade.

Related errors


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