derailed/k9s · error
user is not authorized to delete %s
Error message
user is not authorized to delete %s
What it means
Workload.Delete runs a SelfSubjectAccessReview (Client().CanI) for the delete verb on the workload's GVR before issuing the delete. If the review says not-allowed, the delete is refused client-side and the API server is never called.
Source
Thrown at internal/dao/workload.go:51
client.StsGVR,
client.DpGVR,
client.RsGVR,
}
// Workload tracks a select set of resources in a given namespace.
type Workload struct {
Table
}
func (w *Workload) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, grace Grace) error {
gvr, _ := ctx.Value(internal.KeyGVR).(*client.GVR)
ns, n := client.Namespaced(path)
auth, err := w.Client().CanI(ns, gvr, n, []string{client.DeleteVerb})
if err != nil {
return err
}
if !auth {
return fmt.Errorf("user is not authorized to delete %s", path)
}
var gracePeriod *int64
if grace != DefaultGrace {
gracePeriod = (*int64)(&grace)
}
opts := metav1.DeleteOptions{
PropagationPolicy: propagation,
GracePeriodSeconds: gracePeriod,
}
ctx, cancel := context.WithTimeout(ctx, w.Client().Config().CallTimeout())
defer cancel()
d, err := w.Client().DynDial()
if err != nil {
return err
}View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Confirm with kubectl auth can-i delete <resource>.<group> -n <ns> (same user)
- Add verbs: ["delete"] (and deletecollection if bulk deletes are needed) for that resource to the bound Role/ClusterRole
- Apply the RoleBinding or switch context to a user with delete rights
- If RBAC cannot change, delete from an authorized context: kubectl delete <resource> <name> -n <ns>
Example fix
# before verbs: ["get", "list", "watch"] # after verbs: ["get", "list", "watch", "delete"]
Defensive patterns
Strategy: validation
Validate before calling
allowed, err := k8sClient.CanI(ns, gvr, name, []string{"delete"})
if err != nil { return err }
if !allowed {
return fmt.Errorf("missing delete on %s in %s — grant it or use an authorized context", gvr, ns)
} Try / catch
if err := w.Delete(ctx, path, propagation, grace); err != nil {
if strings.Contains(err.Error(), "not authorized to delete") {
return confirmAndRetryWithPrivilegedContext(path) // or abort with an RBAC hint
}
return err
} Prevention
- Gate delete buttons/actions on a CanI pre-check so unauthorized users never trigger the call
- Document required verbs per role for teams using restricted kubeconfigs
When it happens
Trigger: Deleting any workload through Workload.Delete with a kubeconfig user whose Role/ClusterRole lacks the delete verb for that resource in that namespace (e.g. view-only roles, CI tokens, impersonated under-privileged users).
Common situations: Read-only viewer bindings in production clusters; service accounts used by pipelines that can list but not delete; assuming a restricted identity via k9s --as-user flag.
Related errors
- user is not authorized to delete %s
- user is not authorized to run jobs
- user is not authorized to (un)suspend cronjobs
- user is not authorized to patch a deployment
- user is not authorized to scale: %s
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/969bfbb630222da0.
Report an issue: GitHub.