KubeErrors

Error from server (Forbidden): The request was authenticated and RBAC denied it

A Forbidden error means Kubernetes knows who you are and has decided you may not do this. The message names the user, the verb, and the resource, which is everything needed to write the missing rule.

Applies to: All Kubernetes versions with RBAC enabled

What it means

Authentication and authorization are separate stages, and Forbidden is a failure of the second. The identity was established successfully; the request was then evaluated against RBAC and no rule permitted it. The message follows a fixed shape — User "…" cannot list resource "pods" in API group "" in the namespace "…" — and every field in it is needed to fix the problem. Two of them are easy to misread. An empty API group means the core group, which is what most common resources are in, not a missing value. And a message that says at the cluster scope means the request was not namespaced, which requires a ClusterRole and a ClusterRoleBinding rather than their namespaced equivalents.

Most common causes

How to diagnose it

  1. Read every field of the message: the user, the verb, the resource, the API group, and the namespace or cluster scope.
  2. Check your own effective permission: kubectl auth can-i list pods -n NAMESPACE.
  3. Check another identity's: kubectl auth can-i list pods --as=system:serviceaccount:NS:NAME -n NAMESPACE. This is the fastest way to test a workload's access without deploying anything.
  4. Find the bindings that apply: kubectl get rolebindings,clusterrolebindings --all-namespaces -o wide | grep NAME.
  5. Read the role's actual rules: kubectl describe clusterrole NAME.
  6. For a workload, confirm which ServiceAccount it runs as: kubectl get pod POD -o jsonpath='{.spec.serviceAccountName}'. An empty value means default.

How to fix it

  1. Add a rule granting exactly the verb, resource, and API group named in the error — no more.
  2. Bind at the right scope: a RoleBinding for one namespace, a ClusterRoleBinding for cluster-wide access. A ClusterRole referenced by a RoleBinding grants only within that namespace, which is a useful and frequently missed pattern.
  3. Give the workload a dedicated ServiceAccount rather than relying on default.
  4. Grant subresources explicitly where they are needed — pods/log and pods/exec are separate from pods.
  5. Verify with kubectl auth can-i after changing anything, rather than redeploying to find out.

Notes

RBAC is purely additive: there are no deny rules, so a permission that exists cannot be revoked by adding another rule. Removing access means removing or narrowing the binding that grants it, which is worth knowing before searching for a deny rule that does not exist.

Related

Sources

Pages on this site are written with AI assistance from the primary sources listed on each page, then checked against those sources before publishing.