argoproj/argo-workflows · error

invalid ConcurrencyPolicy: %s

Error message

invalid ConcurrencyPolicy: %s

What it means

enforceRuntimePolicy validates spec.concurrencyPolicy on a CronWorkflow. Only AllowConcurrent, ForbidConcurrent, and ReplaceConcurrent are valid; any other string hits the switch's default and aborts this cron evaluation with this error.

Source

Thrown at workflow/cron/operator.go:287

		case v1alpha1.AllowConcurrent, "":
			// Do nothing
		case v1alpha1.ForbidConcurrent:
			if len(woc.cronWf.Status.Active) > 0 {
				woc.metrics.CronWfPolicy(ctx, woc.cronWf.Name, woc.cronWf.Namespace, v1alpha1.ForbidConcurrent)
				woc.log.Info(ctx, "'ConcurrencyPolicy: Forbid' and has an active Workflow so it was not run")
				return false, nil
			}
		case v1alpha1.ReplaceConcurrent:
			if len(woc.cronWf.Status.Active) > 0 {
				woc.metrics.CronWfPolicy(ctx, woc.cronWf.Name, woc.cronWf.Namespace, v1alpha1.ReplaceConcurrent)
				woc.log.Info(ctx, "'ConcurrencyPolicy: Replace' and has active Workflows")
				err := woc.terminateOutstandingWorkflows(ctx)
				if err != nil {
					return false, err
				}
			}
		default:
			return false, fmt.Errorf("invalid ConcurrencyPolicy: %s", woc.cronWf.Spec.ConcurrencyPolicy)
		}
	}
	return true, nil
}

func (woc *cronWfOperationCtx) terminateOutstandingWorkflows(ctx context.Context) error {
	for _, wfObjectRef := range woc.cronWf.Status.Active {
		woc.log.WithField("name", wfObjectRef.Name).Info(ctx, "stopping")
		err := util.TerminateWorkflow(ctx, woc.wfClient, wfObjectRef.Name)
		if err != nil {
			if apierrors.IsNotFound(err) {
				woc.log.WithField("name", wfObjectRef.Name).Warn(ctx, "workflow not found when trying to terminate outstanding workflows")
				continue
			}
			if alreadyShutdownErr, ok := errors.AsType[util.AlreadyShutdownError](err); ok {
				woc.log.Warn(ctx, alreadyShutdownErr.Error())
				continue
			}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Set concurrencyPolicy to one of: Allow, Forbid, Replace (or omit it)
  2. Run argo lint on the CronWorkflow to catch invalid enum values before submitting
  3. Fix the field with kubectl edit cronworkflow <name> or update the manifest
  4. Check CRD/schema version mismatch if a previously-valid value is now rejected

Example fix

// before
spec:
  concurrencyPolicy: AllowConcurrent
// after
spec:
  concurrencyPolicy: Allow
Defensive patterns

Strategy: validation

Validate before calling

# valid values: Allow | Forbid | Replace (or omit)
kubectl get cronworkflow <name> -o jsonpath='{.spec.concurrencyPolicy}'

Type guard

var valid = map[string]bool{"": true, "Allow": true, "Forbid": true, "Replace": true}
if !valid[policy] {
    return fmt.Errorf("invalid ConcurrencyPolicy: %s", policy)
}

Try / catch

canProceed, err := enforceRuntimePolicy(ctx)
if err != nil {
    // fix spec.concurrencyPolicy in the CronWorkflow, then re-run
    return canProceed, err
}

Prevention

When it happens

Trigger: A CronWorkflow is submitted or updated with concurrencyPolicy set to something other than "", Allow, Forbid, or Replace — enforcement happens when the cron operator runs (run -> enforceRuntimePolicy).

Common situations: Typos like "AllowConcurrent" vs "Allow"; YAML written against Kubernetes CronJob semantics ("Forbid" works, but misspellings like "allowconcurrent" or "forbidden" do not); tooling generating invalid values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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