derailed/k9s · error
user is not authorized to run jobs
Error message
user is not authorized to run jobs
What it means
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.
Source
Thrown at internal/dao/cronjob.go:54
// ListImages lists container images.
func (c *CronJob) ListImages(_ context.Context, fqn string) ([]string, error) {
cj, err := c.GetInstance(fqn)
if err != nil {
return nil, err
}
return render.ExtractImages(&cj.Spec.JobTemplate.Spec.Template.Spec), nil
}
// Run a CronJob.
func (c *CronJob) Run(path string) error {
ns, n := client.Namespaced(path)
auth, err := c.Client().CanI(ns, client.JobGVR, n, []string{client.GetVerb, client.CreateVerb})
if err != nil {
return err
}
if !auth {
return fmt.Errorf("user is not authorized to run jobs")
}
o, err := c.getFactory().Get(c.gvr, path, true, labels.Everything())
if err != nil {
return err
}
var cj batchv1.CronJob
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &cj)
if err != nil {
return errors.New("expecting CronJob resource")
}
jobName := cj.Name
if len(cj.Name) >= maxJobNameSize {
jobName = cj.Name[0:maxJobNameSize]
}
trueVal := true
job := &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{View on GitHub (pinned to 2d3ccc6ba2)
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
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight the exact SSAR check Run uses before offering the trigger action.
func CanTrigger(c client.Client, ns string) (bool, error) {
return c.CanI(ns, client.JobGVR, "", []string{client.GetVerb, client.CreateVerb})
} Try / catch
if err := cj.Run(path); err != nil {
if strings.Contains(err.Error(), "not authorized to run jobs") {
log.Printf("trigger blocked by RBAC: grant get+create on jobs.batch in %s", ns)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- user is not authorized to (un)suspend cronjobs
- user is not authorized to patch a deployment
- user is not authorized to scale: %s
- user is not authorized to restart %q
- user is not authorized to delete %s
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/0660f5963c49b69c.
Report an issue: GitHub.