derailed/k9s · error
user is not authorized to list nodes
Error message
user is not authorized to list nodes
What it means
FetchNode gates the read with a CanI authorization check for the get verb on the nodes resource at cluster scope and returns this error when access is denied. Note the message says "list" although the check actually performed is a get on a single named node — a wording quirk in the DAO.
Source
Thrown at internal/dao/node.go:276
if err != nil {
return false, err
}
return o.Spec.Unschedulable, nil
}
// ----------------------------------------------------------------------------
// Helpers...
// FetchNode retrieves a node.
func FetchNode(_ context.Context, f Factory, path string) (*v1.Node, error) {
_, n := client.Namespaced(path)
auth, err := f.Client().CanI(client.ClusterScope, client.NodeGVR, n, client.GetAccess)
if err != nil {
return nil, err
}
if !auth {
return nil, fmt.Errorf("user is not authorized to list nodes")
}
o, err := f.Get(client.NodeGVR, client.FQN(client.ClusterScope, path), true, labels.Everything())
if err != nil {
return nil, err
}
var node v1.Node
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &node)
if err != nil {
return nil, err
}
return &node, nil
}
// FetchNodes retrieves all nodes.
func FetchNodes(_ context.Context, f Factory, _ string) (*v1.NodeList, error) {View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Grant node read access: a ClusterRole with apiGroups [""] resources ["nodes"] verbs ["get","list"] (or bind the built-in view ClusterRole)
- Verify as the same user: kubectl auth can-i get nodes
- Switch to a kubeconfig context with cluster read if node inspection is required
Example fix
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: node-reader rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list"]
Defensive patterns
Strategy: validation
Validate before calling
ok, err := factory.Client().CanI(client.ClusterScope, client.NodeGVR, nodeName, client.GetAccess)
if err != nil { return err }
if !ok { return fmt.Errorf("missing get on nodes for this identity") } Try / catch
if _, err := dao.FetchNode(ctx, f, path); err != nil {
if strings.Contains(err.Error(), "not authorized to list nodes") {
// terminal RBAC gap: stop and prompt for credentials/role, do not retry
}
} Prevention
- Run kubectl auth can-i get nodes as a preflight for any node-dependent feature
- Grant get+list on nodes together — the DAO needs both across its node APIs
- Remember this message can mean 'get' denied even though it says list
When it happens
Trigger: CanI(cluster-scope, nodes, <name>, get) returns false — the kubeconfig user lacks the get verb on core nodes.
Common situations: Restricted service accounts (CI runners, GitOps) with only namespace-scoped roles; kubeconfig using a tenant/limited user; policy engines (OPA/Kyverno) denying node reads; users misled by the 'list' wording into granting the wrong verb.
Related errors
- user is not authorized to list node metrics
- user is not authorized to list pods metrics
- user is not authorized to list pod metrics
- (%s) access denied for user on resource %q:%s in namespace %
- user is not authorized to run jobs
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/6d6d572068760e7f.
Report an issue: GitHub.