argoproj/argo-workflows · error

unable to compress or offload workflow nodes: %w

Error message

unable to compress or offload workflow nodes: %w

What it means

During resume/retry-style reconciliation in workflow/util, when node status was changed the controller dehydrates (compresses/offloads) the workflow node status before updating the object via hydrator.Dehydrate. If compression or SQL offloading fails, the update is aborted with this error. It protects the cluster from writing an over-sized Workflow object that the API server or etcd would reject.

Source

Thrown at workflow/util/util.go:567

			if node.IsActiveSuspendNode() {
				if err := OverrideOutputParametersWithDefault(node.Outputs); err != nil {
					return false, err
				}
				node.Phase = wfv1.NodeSucceeded
				if node.Message != "" {
					uiMsg = node.Message + "; " + uiMsg
				}
				node.Message = uiMsg
				node.FinishedAt = metav1.Time{Time: time.Now().UTC()}
				wf.Status.Nodes.Set(ctx, nodeID, node)
				workflowUpdated = true
			}
		}

		if workflowUpdated {
			err := hydrator.Dehydrate(ctx, wf)
			if err != nil {
				return false, fmt.Errorf("unable to compress or offload workflow nodes: %w", err)
			}
			creator.LabelActor(ctx, wf, creator.ActionResume)
			_, err = wfIf.Update(ctx, wf, metav1.UpdateOptions{})
			if err != nil {
				if apierr.IsConflict(err) {
					return false, nil
				}
				return false, err
			}
		}
		return true, nil
	})
	return err
}

func SelectorMatchesNode(selector fields.Selector, node wfv1.NodeStatus) bool {
	nodeFields := fields.Set{
		"displayName":  node.DisplayName,

View on GitHub (pinned to 35bff19146)

Solutions

  1. Verify the workflow-controller-configmap persistence settings (archive, postgresql/mysql host, credentials) and that the DB is reachable.
  2. Check controller logs for the wrapped hydrator/persist error for the exact cause.
  3. Reduce node status size (avoid huge captured outputs/parameters in nodes) or archive/clean old workflows.
  4. Retry the operation once the database is healthy.

Example fix

// before (workflow-controller-configmap)
persistence: {}
// after
persistence:
  archive: true
  postgresql:
    host: postgres.postgres
    database: argo
    userNameSecret: {name: argo-postgres-config}
    passwordSecret: {name: argo-postgres-config}
Defensive patterns

Strategy: retry

Validate before calling

cfg, _ := config.ControllerConfig()
if cfg.Persistence == nil || !cfg.Persistence.Archive {
	// offloading disabled; large workflows will fail dehydrate
}

Try / catch

updated, err := util.OperateWorkflow(ctx, ...)
if err != nil && strings.Contains(err.Error(), "unable to compress or offload workflow nodes") {
	// transient: requeue and retry after checking DB health
	return requeueAfter(time.Minute)
}

Prevention

When it happens

Trigger: Resuming/operating on a workflow whose Status.Nodes exceeds the in-object size limit and whose offload target (SQL archive database) is unreachable, misconfigured, or fails; or compression of the node status fails.

Common situations: Misconfigured persistence (persistence section in workflow-controller-configmap pointing at a down Postgres/MySQL), expired DB credentials, or very large node histories from deeply-fanned-out DAGs.

Related errors


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