argoproj/argo-workflows · error

failed to marshal container args for %s: %w

Error message

failed to marshal container args for %s: %w

What it means

workflowpod build could not json.Marshal a main/sidecar container's Args while checking whether they exceed the size limit for exec-based offloading. Marshal of []string args essentially cannot fail, so this is a defensive guard; the container name is included.

Source

Thrown at workflow/controller/workflowpod.go:814

		}
		pod.Spec.Containers[i] = c
	}

	offloadEnvVarTemplate := false
	offloadContainerArgs := false
	var containerArgsValue string
	var containerArgsName string

	// Check if main container args need offloading (too large for exec)
	for _, c := range pod.Spec.Containers {
		if common.IsArgoSidecar(c.Name) { // skip wait, supervisor, and artifact plugin sidecars
			continue
		}
		if c.Args != nil {
			var argsJSON []byte
			argsJSON, err = json.Marshal(c.Args)
			if err != nil {
				return nil, fmt.Errorf("failed to marshal container args for %s: %w", c.Name, err)
			}
			if len(argsJSON) > common.MaxEnvVarLen {
				offloadContainerArgs = true
				containerArgsValue = string(argsJSON)
				containerArgsName = c.Name
				break
			}
		}
	}

	// Scan every container that may carry ARGO_TEMPLATE. Legacy mode puts it on
	// the init container; init-less mode puts it on the supervisor (always) and
	// on the main container for templates without a supervisor (data /
	// resource-without-logs). Missing any of those when oversized re-introduces
	// the "pod spec too large" rejection that the offload path is here to fix.
	_ = eachContainer(pod, func(c *apiv1.Container) error {
		for _, e := range c.Env {
			if e.Name == common.EnvVarTemplate {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Inspect the wrapped marshal error in the controller log
  2. Ensure template container args are plain strings in the Workflow spec
  3. Validate the Workflow with argo lint before submitting
  4. Check for custom controllers/operators mutating the workflow pod spec

Example fix

// before
args: ["--flag", 42]
// after
args: ["--flag", "42"]
Defensive patterns

Strategy: validation

Validate before calling

// args must be an array of strings in the template spec
// argo lint my-wf.yaml

Try / catch

if argsJSON, err := json.Marshal(c.Args); err != nil {
    return nil, fmt.Errorf("failed to marshal container args for %s: %w", c.Name, err)
}

Prevention

When it happens

Trigger: json.Marshal(c.Args) returns an error — practically only for unsupported values in args; args are []string so this is nearly unreachable except via corrupted/programmatically built templates, or an oversized/odd arg payload path in custom code.

Common situations: Template specs generated by tooling that inject non-string arg values; bugs in controllers/plugins mutating pod specs; extremely large args arrays interacting with MaxEnvVarLen offload logic.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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