{"record":{"id":"0660f5963c49b69c","repo":"derailed/k9s","slug":"user-is-not-authorized-to-run-jobs","errorCode":null,"errorMessage":"user is not authorized to run jobs","messagePattern":"user is not authorized to run jobs","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/cronjob.go","lineNumber":54,"sourceCode":"// ListImages lists container images.\nfunc (c *CronJob) ListImages(_ context.Context, fqn string) ([]string, error) {\n\tcj, err := c.GetInstance(fqn)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn render.ExtractImages(&cj.Spec.JobTemplate.Spec.Template.Spec), nil\n}\n\n// Run a CronJob.\nfunc (c *CronJob) Run(path string) error {\n\tns, n := client.Namespaced(path)\n\tauth, err := c.Client().CanI(ns, client.JobGVR, n, []string{client.GetVerb, client.CreateVerb})\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !auth {\n\t\treturn fmt.Errorf(\"user is not authorized to run jobs\")\n\t}\n\n\to, err := c.getFactory().Get(c.gvr, path, true, labels.Everything())\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar cj batchv1.CronJob\n\terr = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &cj)\n\tif err != nil {\n\t\treturn errors.New(\"expecting CronJob resource\")\n\t}\n\tjobName := cj.Name\n\tif len(cj.Name) >= maxJobNameSize {\n\t\tjobName = cj.Name[0:maxJobNameSize]\n\t}\n\ttrueVal := true\n\tjob := &batchv1.Job{\n\t\tObjectMeta: metav1.ObjectMeta{","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/cronjob.go#L36-L72","documentation":"CronJob.Run (internal/dao/cronjob.go:48-57) triggers a CronJob by creating a Job from its template. Before doing so it asks SelfSubjectAccessReview (client.CanI) for get AND create on jobs.batch in the target namespace; if either is denied it returns this error without touching the cluster.","triggerScenarios":"Invoking the k9s trigger/run action on a CronJob while the current kubeconfig user or service account lacks `get jobs` or `create jobs` in that namespace. The check is namespace- and verb-specific; ownership of the CronJob itself is irrelevant.","commonSituations":"View-only RBAC roles (granted get/list on everything but no create); CI service accounts used with k9s; restricted namespaces where developers may inspect cronjobs but only a pipeline may fire them.","solutions":["Check what you lack: kubectl auth can-i create jobs -n <ns> and kubectl auth can-i get jobs -n <ns>","Grant both verbs in a Role + RoleBinding, e.g. rules: - apiGroups: [\"batch\"] resources: [\"jobs\"] verbs: [\"get\",\"create\"]","Or run k9s with a context/user that already has the permission","If you only meant to inspect the CronJob, use describe/view instead of trigger"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight the exact SSAR check Run uses before offering the trigger action.\nfunc CanTrigger(c client.Client, ns string) (bool, error) {\n\treturn c.CanI(ns, client.JobGVR, \"\", []string{client.GetVerb, client.CreateVerb})\n}","typeGuard":null,"tryCatchPattern":"if err := cj.Run(path); err != nil {\n    if strings.Contains(err.Error(), \"not authorized to run jobs\") {\n        log.Printf(\"trigger blocked by RBAC: grant get+create on jobs.batch in %s\", ns)\n    }\n    return err\n}","preventionTips":["Include verbs [get, create] on jobs.batch in any role expected to fire CronJobs","Run kubectl auth can-i create jobs -n <ns> once when onboarding a kubeconfig to k9s","Keep a privileged break-glass context documented for on-call triggers"],"tags":["go","kubernetes","rbac","k9s","cronjob","authorization"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}