argoproj/argo-workflows · error
workflows must use workflowTemplateRef to be executed when t
Error message
workflows must use workflowTemplateRef to be executed when the controller is in reference mode
What it means
When the controller is configured with workflowRestrictions.templateReferencing: Strict/Secure (reference mode), it rejects any workflow that does not use workflowTemplateRef. The reconciliation marks the workflow Error with this message and returns it.
Source
Thrown at workflow/controller/operator.go:4502
// When workflow restrictions require template referencing (Strict/Secure mode),
// reject workflows that set any non-allowed fields, as they could override
// security settings defined in the WorkflowTemplate.
if woc.controller.Config.WorkflowRestrictions.MustUseReference() { // not-woc-misuse: intentionally checking the user-submitted spec
if err := wfutil.ValidateUserOverrides(&woc.wf.Spec); err != nil { //nolint:forbidigo // not-woc-misuse
ctx = woc.markWorkflowError(ctx, err)
return ctx, err
}
}
err := woc.setStoredWfSpec(ctx)
if err != nil {
ctx = woc.markWorkflowError(ctx, err)
return ctx, err
}
woc.execWf = &wfv1.Workflow{Spec: *woc.wf.Status.StoredWorkflowSpec.DeepCopy()}
woc.volumes = woc.execWf.Spec.DeepCopy().Volumes
setWfTemplateLabel(woc.wf)
case woc.controller.Config.WorkflowRestrictions.MustUseReference():
err := fmt.Errorf("workflows must use workflowTemplateRef to be executed when the controller is in reference mode")
ctx = woc.markWorkflowError(ctx, err)
return ctx, err
default:
err := woc.controller.setWorkflowDefaults(woc.wf)
if err != nil {
ctx = woc.markWorkflowError(ctx, err)
return ctx, err
}
woc.volumes = woc.wf.Spec.DeepCopy().Volumes //nolint:forbidigo // not-woc-misuse
}
// Perform one-time workflow validation
if woc.wf.Status.Phase == wfv1.WorkflowUnknown {
validateOpts := validate.Opts{}
wftmplGetter := templateresolution.WrapWorkflowTemplateInterface(woc.controller.wfclientset.ArgoprojV1alpha1().WorkflowTemplates(woc.wf.Namespace))
cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(woc.controller.wfclientset.ArgoprojV1alpha1().ClusterWorkflowTemplates())
// Validate the execution wfSpecView on GitHub (pinned to 35bff19146)
Solutions
- Set spec.workflowTemplateRef.name on the workflow, moving its spec content into a WorkflowTemplate
- Remove or relax the workflowRestrictions.templateReferencing setting in the controller ConfigMap if inline specs are allowed
- Update CI/templates so all submissions go through WorkflowTemplates
Example fix
// before (controller config)
workflowRestrictions:
templateReferencing: Strict
// with inline-spec workflow -> either remove restriction or use:
// after
spec:
workflowTemplateRef:
name: my-template Defensive patterns
Strategy: validation
Validate before calling
if controllerConfig.WorkflowRestrictions != nil && wf.Spec.WorkflowTemplateRef == nil {
return fmt.Errorf("reference mode enabled: workflow must use workflowTemplateRef")
} Try / catch
if strings.Contains(err.Error(), "reference mode") {
// resubmit using a WorkflowTemplate reference
} Prevention
- Know your controller's workflowRestrictions config
- Standardize submissions through WorkflowTemplates
- Add CI linting that requires workflowTemplateRef in restricted namespaces
When it happens
Trigger: Submitting a workflow with an inline spec (no spec.workflowTemplateRef) to a controller whose config sets workflowRestrictions.templateReferencing, causing MustUseReference() to be true during operate().
Common situations: Namespace-wide policy enforcement enabled but legacy inline-spec workflows still exist; CI pipelines submitting hand-written specs after an admin hardened the controller config.
Related errors
- cannot fetch workflow spec without workflowTemplateRef
- failed to read container args file %s: %w
- failed to unmarshal container args: %w
- failed to read template: %w
- failed to start command: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/59a2463d120b8666.
Report an issue: GitHub.