Kubernetes ServiceAccount cannot list nodes
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If a Kubernetes ServiceAccount cannot list nodes, the problem is almost always RBAC rather than authentication. Nodes are a cluster-scoped resource, so the fix usually requires a ClusterRole and ClusterRoleBinding, not a namespaced Role.
Why Listing Nodes Is Different
Kubernetes resources fall into two broad groups:
- namespaced resources such as pods and config maps
- cluster-scoped resources such as nodes
That distinction matters because a regular Role only grants permissions inside one namespace. Since nodes live at the cluster level, a service account that needs to list them must be granted a cluster-scoped permission.
That is why a service account can sometimes list pods in its namespace but still fail on:
when used through the API.
Create a ClusterRole That Allows Listing Nodes
A minimal RBAC policy for reading node objects looks like this:
This allows read-only access to node metadata. It does not grant write access or broad admin privileges.
Bind the Role to the Service Account
After defining the role, bind it to the service account with a ClusterRoleBinding:
Apply both manifests:
Now pods running as default/app-sa can authenticate as that service account and list nodes.
Verify the Permission Before Debugging the App
Kubernetes gives you a direct way to test the effective permission:
If this command says no, the application is not the problem. The RBAC policy is still insufficient or bound to the wrong subject.
That check is much faster than staring at client library code or pod logs first.
A Pod Example
Here is a pod that runs with the service account:
Once the pod is running, you can test from inside it:
If RBAC is correct and the image has credentials mounted through the service account token, this should work.
Do Not Use a Namespaced Role for Nodes
One of the most common mistakes is writing something like this:
This will not solve the problem because nodes are not namespaced. Even if the rule syntax looks correct, the scope is wrong.
For nodes, the pattern is:
- '
ClusterRole' - '
ClusterRoleBinding'
not:
- '
Role' - '
RoleBinding'
Grant Only What You Actually Need
Listing nodes can expose cluster topology and labels, so grant it only if the workload truly needs it. Many applications do not need direct node access at all. If the requirement is actually “discover my own node name,” there may be safer alternatives such as exposing relevant data through the Downward API or specific controller logic.
RBAC fixes should be minimal, not just broad enough to make the error disappear.
Common Pitfalls
- Using a namespaced
Rolewhen the resource is cluster-scoped. - Binding the permission to the wrong namespace or service account name.
- Debugging client code before verifying the RBAC decision with
kubectl auth can-i. - Granting broad cluster-admin access when read-only node access would be enough.
- Forgetting that the pod must actually run as the intended service account.
Summary
- Nodes are cluster-scoped resources, so service accounts need cluster-scoped RBAC to list them.
- Use a
ClusterRolewithget,list, andwatchonnodes. - Bind that role with a
ClusterRoleBindingto the correct service account. - Verify the permission with
kubectl auth can-ibefore debugging application code. - Keep the permission as narrow as possible, because many workloads do not need node access at all.

