derailed/k9s · error

user is not authorized to delete %s

Error message

user is not authorized to delete %s

What it means

Generic.Delete (internal/dao/generic.go:108-119) performs authorization before destruction: it requires the delete verb on the resource's GVR in its namespace (client.CanI). Denial returns this error printing the resource path (namespace/name - the message does not include the GVR kind).

Source

Thrown at internal/dao/generic.go:117

		return "", err
	}

	raw, err := ToYAML(o, showManaged)
	if err != nil {
		return "", fmt.Errorf("unable to marshal resource %w", err)
	}
	return raw, nil
}

// Delete deletes a resource.
func (g *Generic) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, grace Grace) error {
	ns, n := client.Namespaced(path)
	auth, err := g.Client().CanI(ns, g.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,
	}

	dial, err := g.dynClient()
	if err != nil {
		return err
	}
	if client.IsClusterScoped(ns) {
		return dial.Delete(ctx, n, opts)
	}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Verify: kubectl auth can-i delete <resource> -n <ns>
  2. Grant verbs: ["delete"] on the resource in a Role and bind it, or escalate to the break-glass identity
  3. Use namespace deletion or a pipeline with sufficient permission if per-object delete is locked
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight the delete verb before showing/enabling the delete action.
func CanDelete(c client.Client, gvr *client.GVR, ns, n string) (bool, error) {
	return c.CanI(ns, gvr, n, []string{client.DeleteVerb})
}

Try / catch

if err := g.Delete(ctx, path, propagation, grace); err != nil {
    if strings.Contains(err.Error(), "not authorized to delete") {
        return fmt.Errorf("RBAC: grant verbs:[delete] on %s in namespace %s (kubectl auth can-i delete %s -n %s)", g.gvr, ns, g.gvr, ns)
    }
    return err
}

Prevention

When it happens

Trigger: Pressing ctrl-d / delete on any resource while the identity lacks `delete` on that resource type in that namespace. Grace period and propagation options are irrelevant - the call is blocked before any API request.

Common situations: View-only auditors in production namespaces; namespaces where deletion is reserved to a CI service account; users forgetting k9s is bound to a privileged context and testing RBAC restrictions.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/bd2ac31a8682a377. Report an issue: GitHub.