{"record":{"id":"3c1ebe10f179fb86","repo":"argoproj/argo-workflows","slug":"invalid-spec-clusterworkflowtemplates-argoproj-io","errorCode":null,"errorMessage":"invalid spec: clusterworkflowtemplates.argoproj.io `%s` is forbidden: User cannot get resource 'clusterworkflowtemplates' in API group argoproj.io at the cluster scope","messagePattern":"invalid spec: clusterworkflowtemplates\\.argoproj\\.io `(.+?)` is forbidden: User cannot get resource 'clusterworkflowtemplates' in API group argoproj\\.io at the cluster scope","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/templateresolution/context.go","lineNumber":56,"sourceCode":"// clusterWorkflowTemplateInterfaceWrapper is an internal struct to wrap clientset.\ntype clusterWorkflowTemplateInterfaceWrapper struct {\n\tclientset typed.ClusterWorkflowTemplateInterface\n}\n\n// ClusterWorkflowTemplateGetter helps get WorkflowTemplates.\ntype ClusterWorkflowTemplateGetter interface {\n\t// Get retrieves the WorkflowTemplate from the indexer for a given name.\n\tGet(ctx context.Context, name string) (*wfv1.ClusterWorkflowTemplate, error)\n}\n\nfunc WrapClusterWorkflowTemplateInterface(clusterClientset typed.ClusterWorkflowTemplateInterface) ClusterWorkflowTemplateGetter {\n\treturn &clusterWorkflowTemplateInterfaceWrapper{clientset: clusterClientset}\n}\n\ntype NullClusterWorkflowTemplateGetter struct{}\n\nfunc (n *NullClusterWorkflowTemplateGetter) Get(_ context.Context, name string) (*wfv1.ClusterWorkflowTemplate, error) {\n\treturn nil, errors.Errorf(\"\", \"invalid spec: clusterworkflowtemplates.argoproj.io `%s` is \"+\n\t\t\"forbidden: User cannot get resource 'clusterworkflowtemplates' in API group argoproj.io at the cluster scope\", name)\n}\n\n// Get retrieves the WorkflowTemplate of a given name.\nfunc (wrapper *clusterWorkflowTemplateInterfaceWrapper) Get(ctx context.Context, name string) (*wfv1.ClusterWorkflowTemplate, error) {\n\treturn wrapper.clientset.Get(ctx, name, metav1.GetOptions{})\n}\n\n// TemplateContext is a context of template search.\ntype TemplateContext struct {\n\t// wftmplGetter is an interface to get WorkflowTemplates.\n\twftmplGetter WorkflowTemplateNamespacedGetter\n\t// cwftmplGetter is an interface to get ClusterWorkflowTemplates\n\tcwftmplGetter ClusterWorkflowTemplateGetter\n\t// tmplBase is the base of local template search.\n\ttmplBase wfv1.TemplateHolder\n\t// workflow is the Workflow where templates will be stored\n\tworkflow *wfv1.Workflow","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/templateresolution/context.go#L38-L74","documentation":"When a workflow references a template from a ClusterWorkflowTemplate, the controller uses a cluster-scoped clientset. If the ClusterWorkflowTemplateGetter is the Null implementation (no cluster template support configured/authorized), Get always returns this fixed RBAC-forbidden error so template resolution fails with a k8s-style forbidden message.","triggerScenarios":"templateRef with clusterScope: true while the installation has no ClusterWorkflowTemplate CRD support or the caller lacks RBAC to get clusterworkflowtemplates at cluster scope.","commonSituations":"Namespaced-only argo deployments (cluster workflow templates feature disabled); RBAC policies blocking cluster-scoped reads for the controller or the submitting user via SSO.","solutions":["Grant the caller/controller RBAC get on clusterworkflowtemplates.argoproj.io at cluster scope","Remove clusterScope: true and use a namespace-local WorkflowTemplate","Deploy the ClusterWorkflowTemplate CRD / enable cluster template support in the controller"],"exampleFix":"// before\ntemplateRef:\n  name: my-cluster-template\n  template: step\n  clusterScope: true\n// after\ntemplateRef:\n  name: my-template\n  template: step\n  clusterScope: false","handlingStrategy":"fallback","validationCode":"// check RBAC before submitting a clusterScope templateRef\nkubectl auth can-i get clusterworkflowtemplates.argoproj.io --as=<user>","typeGuard":null,"tryCatchPattern":"tpl, err := tplCtx.GetTemplateByName(ctx, name)\nif err != nil && strings.Contains(err.Error(), \"forbidden\") {\n  // fall back to namespaced WorkflowTemplate or report RBAC misconfiguration\n}","preventionTips":["Verify controller and user RBAC cover clusterworkflowtemplates if using clusterScope: true","Prefer namespaced WorkflowTemplates when cluster templates aren't installed","Lint with `argo lint` using the same RBAC context as submission"],"tags":["kubernetes","rbac","clusterworkflowtemplate","forbidden","argo-workflows"],"backgroundTag":"rbac-forbidden-resource","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}