derailed/k9s · error

current user can't edit resource %s

Error message

current user can't edit resource %s

What it means

Before shelling out to kubectl edit, the app verifies RBAC with CanI(ns, gvr, name, PatchAccess); it returned either not-allowed or an error. kubectl edit patches the resource, so the user needs patch (and typically get) permission on that specific object. Note the underlying err is discarded — the same message appears for genuine denial and for an API failure inside CanI.

Source

Thrown at internal/view/browser.go:567

		b.App().Flash().Err(err)
	}

	return nil
}

func editRes(app *App, gvr *client.GVR, path string) error {
	if path == "" {
		return fmt.Errorf("nothing selected %q", path)
	}
	ns, n := client.Namespaced(path)
	if n == "" {
		return fmt.Errorf("missing resource name in path %q", path)
	}
	if client.IsClusterScoped(ns) {
		ns = client.BlankNamespace
	}
	if ok, err := app.Conn().CanI(ns, gvr, n, client.PatchAccess); !ok || err != nil {
		return fmt.Errorf("current user can't edit resource %s", gvr)
	}

	args := make([]string, 0, 10)
	args = append(args, "edit", gvr.FQN(n))
	if ns != client.BlankNamespace {
		args = append(args, "-n", ns)
	}
	if err := runK(app, &shellOpts{clear: true, args: args}); err != nil {
		app.Flash().Errf("Edit command failed: %s", err)
	}

	return nil
}

func (b *Browser) switchNamespaceCmd(evt *tcell.EventKey) *tcell.EventKey {
	i, err := strconv.Atoi(string(evt.Rune()))
	if err != nil {
		slog.Error("Unable to convert keystroke", slogs.Error, err)

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Ask the operator for patch permission: add verbs ["get","patch"] for the resource(verbs include "patch") in a Role/ClusterRole bound to the user.
  2. Verify with kubectl auth can-i patch <resource> <name> -n <ns> to distinguish RBAC denial from an API error.
  3. If CanI errors rather than denies, fix connectivity/apiserver/admission issue and retry; check kube-apiserver logs for SelfSubjectAccessReview failures.
  4. If read-only access is intentional, view YAML instead of editing (y key or equivalent).

Example fix

# before: role allows read-only
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get","list","watch"]

# after: add patch for editing
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get","list","watch","patch"]
Defensive patterns

Strategy: validation

Validate before calling

if ok, err := app.Conn().CanI(ns, gvr, n, client.PatchAccess); err != nil {
    return fmt.Errorf("permission check failed for %s: %w", gvr, err)
} else if !ok {
    return fmt.Errorf("rbac: patch denied on %s/%s, ask operator for patch verb", ns, gvr)
}

Try / catch

if err := editRes(app, gvr, path); err != nil {
    if strings.Contains(err.Error(), "can't edit") {
    // verify out-of-band to distinguish denial vs API failure
    _ = shellRun(app, "kubectl auth can-i patch " + gvr.String() + " -n " + ns)
    }
}

Prevention

When it happens

Trigger: User presses `e` on a resource they can view but not patch: Role/RoleBinding lacking verbs ["patch"], or a Role that grants patch cluster-wide but a tighter RoleRef on the specific object; also when CanI itself errored (API unreachable, SelfSubjectAccessReview broken by admission/OPA).

Common situations: Read-only cluster roles for support/observability teams; dev namespaces with restrictive RBAC; kyverno/OPA mutating or denying SelfSubjectAccessReview; API server connectivity issues mid-session.

Related errors


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