derailed/k9s · error
%v access denied on resource %q:%q
Error message
%v access denied on resource %q:%q
What it means
Factory.CanForResource (internal/watch/factory.go:213) performs a SelfSubjectAccessReview (Client().CanI) for the given verbs on a resource in a namespace. When the server answers 'not allowed', k9s refuses to create an informer and returns this error listing the verbs, namespace and GVR. It is an RBAC denial surfaced before any watch/list attempt.
Source
Thrown at internal/watch/factory.go:213
f.mx.RLock()
defer f.mx.RUnlock()
_, ok := f.factories[client.BlankNamespace]
return ok
}
// CanForResource return an informer is user has access.
func (f *Factory) CanForResource(ns string, gvr *client.GVR, verbs []string) (informers.GenericInformer, error) {
var resName string
if gvr == client.NsGVR {
resName = ns
}
auth, err := f.Client().CanI(ns, gvr, resName, verbs)
if err != nil {
return nil, err
}
if !auth {
return nil, fmt.Errorf("%v access denied on resource %q:%q", verbs, ns, gvr)
}
// Namespaces are cluster-scoped; always use cluster scope for the informer
if gvr == client.NsGVR {
ns = client.ClusterScope
}
return f.ForResource(ns, gvr)
}
// CanForInstance return an informer is user has access.
func (f *Factory) CanForInstance(fqn string, gvr *client.GVR, verbs []string) (informers.GenericInformer, error) {
ns, n := namespaced(fqn)
if client.IsAllNamespace(ns) {
ns = client.BlankNamespace
}
// For namespace resources, use the resource name as the namespace for RBACView on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Identify the missing verbs from the message and grant them via Role + RoleBinding in that namespace (see exampleFix)
- Verify current identity and permissions: 'kubectl auth whoami' and 'kubectl auth can-i --list -n <ns>'
- Run k9s with a kubeconfig that has broader rights, or point KUBECONFIG at the right context
- If denial is expected, avoid navigating to that resource view; k9s only calls CanForResource for features you invoke
Example fix
# before: [get list watch] access denied on resource "ns1":"apps/v1/deployments"
# after: grant RBAC
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: deploy-viewer
namespace: ns1
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: deploy-viewer-binding
namespace: ns1
subjects:
- kind: User
name: jane
roleRef:
kind: Role
name: deploy-viewer
apiGroup: rbac.authorization.k8s.io Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check with the same SSAR call before building UI on the informer
if ok, err := f.Client().CanI(ns, gvr, "", []string{"get", "list", "watch"}); err == nil && !ok {
// hide/disable the feature instead of erroring later
return nil
} Try / catch
// Go: treat the denial as a control-flow signal, not a crash
inf, err := f.CanForResource(ns, gvr, verbs)
if err != nil {
if strings.Contains(err.Error(), "access denied") {
slog.Warn("rbac denied", slog.String("gvr", gvr.String()), slog.String("ns", ns))
return hideFeature(gvr)
}
return err
} Prevention
- Audit RBAC with 'kubectl auth can-i --list -n <ns>' before pointing k9s at a cluster
- Maintain per-team RoleBindings that include get/list/watch for resources the team browses
- Programmatically call kubectl auth can-i before enabling resource features in tooling
When it happens
Trigger: Opening a view / running a feature that needs informers on a resource the current user has no get/list/watch (or the specific requested verbs) for in that namespace — e.g. ':events' with no list on events, xray on a cluster where the user is namespace-restricted.
Common situations: Restricted service-account kubeconfigs (CI, read-only auditor roles); missing RoleBinding for a new team member; typos in Role resourceNames; freshly created namespace without bindings; cluster-scope-only users browsing other namespaces.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- 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
- user is not authorized to restart %q
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/1f246848d9a7dd30.
Report an issue: GitHub.