Your Kubernetes operation fails with Error from server (Forbidden): ... or pods can't access the Kubernetes API. RBAC (Role-Based Access Control) governs who can do what in Kubernetes, and permission denied errors indicate authorization failures. Understanding RBAC is essential for both cluster administration and application development.

Introduction

This article covers troubleshooting steps and solutions for Fix Kubernetes RBAC Permission Denied Error. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.

Symptoms

Common error messages include:

```bash # For kubectl commands, check current user kubectl config current-context kubectl auth whoami

# For pods, check service account kubectl get pod pod-name -n namespace -o jsonpath='{.spec.serviceAccountName}' ```

```bash # Test if you can perform specific action kubectl auth can-i get pods -n namespace

# Test as specific service account kubectl auth can-i get pods -n namespace --as=system:serviceaccount:namespace:sa-name

# Test as specific user kubectl auth can-i get pods -n namespace --as=user@example.com

# List all allowed actions kubectl auth can-i --list -n namespace ```

```bash # List roles in namespace kubectl get roles -n namespace kubectl describe role role-name -n namespace

# List role bindings kubectl get rolebindings -n namespace kubectl describe rolebinding binding-name -n namespace

# Cluster-wide kubectl get clusterroles kubectl get clusterrolebindings ```

Common Causes

  • Configuration misconfiguration
  • Missing or incorrect credentials
  • Network connectivity issues
  • Version compatibility problems
  • Resource exhaustion or limits
  • Permission or access denied

Understanding Kubernetes RBAC

RBAC controls API access based on roles assigned to users, groups, or service accounts. Permission denied means the requesting identity lacks the necessary role or role binding. The RBAC system checks: who is making the request (subject), what they want to do (verb), and what resource they're accessing (resource).

Step-by-Step Fix

Identify the requesting identity:

```bash # For kubectl commands, check current user kubectl config current-context kubectl auth whoami

# For pods, check service account kubectl get pod pod-name -n namespace -o jsonpath='{.spec.serviceAccountName}' ```

Check existing permissions:

```bash # Test if you can perform specific action kubectl auth can-i get pods -n namespace

# Test as specific service account kubectl auth can-i get pods -n namespace --as=system:serviceaccount:namespace:sa-name

# Test as specific user kubectl auth can-i get pods -n namespace --as=user@example.com

# List all allowed actions kubectl auth can-i --list -n namespace ```

Check roles and bindings:

```bash # List roles in namespace kubectl get roles -n namespace kubectl describe role role-name -n namespace

# List role bindings kubectl get rolebindings -n namespace kubectl describe rolebinding binding-name -n namespace

# Cluster-wide kubectl get clusterroles kubectl get clusterrolebindings ```

Common Solutions

Solution 1: Create Missing Role

Define the required permissions:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: namespace
  name: pod-reader
rules:
- apiGroups: [""]  # Core API group
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

For more permissions:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: namespace
  name: deployment-manager
rules:
- apiGroups: ["", "apps", "extensions"]
  resources: ["deployments", "replicasets", "pods", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

Solution 2: Create RoleBinding

Bind role to subject:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: namespace
  name: pod-reader-binding
subjects:
- kind: ServiceAccount
  name: default
  namespace: namespace
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

For user binding:

```yaml subjects: - kind: User name: user@example.com apiGroup: rbac.authorization.k8s.io

# For group subjects: - kind: Group name: developers apiGroup: rbac.authorization.k8s.io ```

Solution 3: Create ClusterRole for Cross-Namespace Access

ClusterRoles work across all namespaces:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-reader
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

Bind with ClusterRoleBinding:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-reader-binding
subjects:
- kind: ServiceAccount
  name: monitoring
  namespace: monitoring
roleRef:
  kind: ClusterRole
  name: node-reader
  apiGroup: rbac.authorization.k8s.io

Solution 4: Fix Service Account Configuration

Pods use the default service account unless specified:

yaml
# Specify custom service account
spec:
  serviceAccountName: custom-sa

Create dedicated service account:

yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: namespace
  name: custom-sa

Check if token is mounted:

```bash # Verify token exists in pod kubectl exec pod-name -n namespace -- ls /var/run/secrets/kubernetes.io/serviceaccount/

# Check token content kubectl exec pod-name -n namespace -- cat /var/run/secrets/kubernetes.io/serviceaccount/token ```

Solution 5: Fix API Group Specification

Resources belong to specific API groups:

```yaml # Common API groups: # "" (empty) - Core resources: pods, services, configmaps, secrets, namespaces # "apps" - Deployments, StatefulSets, DaemonSets, Replicasets # "batch" - Jobs, CronJobs # "networking.k8s.io" - Ingress, NetworkPolicy # "rbac.authorization.k8s.io" - Roles, RoleBindings

# WRONG: Missing API group for deployments rules: - apiGroups: [""] # Wrong - deployments are in apps resources: ["deployments"]

# CORRECT: rules: - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] ```

Solution 6: Fix Verb Specification

Verbs define allowed actions:

```yaml # Common verbs: # get - Read single resource # list - Read multiple resources # watch - Stream updates # create - Create new resource # update - Update existing resource # patch - Partial update # delete - Delete resource

# For read-only access verbs: ["get", "list", "watch"]

# For full access verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

# For specific subresources rules: - apiGroups: [""] resources: ["pods", "pods/log", "pods/exec"] # pods/log, pods/exec are subresources verbs: ["get"] ```

Solution 7: Fix Resource Names Restrictions

Roles can restrict to specific resources:

yaml
# Restrict to specific resource names
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["app-config", "app-secrets"]  # Only these specific ConfigMaps
  verbs: ["get", "update"]

Remove resourceNames for broader access:

yaml
# Without resourceNames - all ConfigMaps in namespace
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list", "create", "update"]

Solution 8: Use Aggregated ClusterRoles

Combine existing roles:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-view
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.authorization.k8s.io/aggregate-to-view: "true"
  - matchLabels:
      monitoring: "true"
rules: []  # Controller fills in from aggregated roles

Create label for aggregation:

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-metrics-reader
  labels:
    monitoring: "true"
rules:
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods"]
  verbs: ["get", "list"]

Verification

After applying RBAC changes:

```bash # Test permission kubectl auth can-i get pods -n namespace --as=system:serviceaccount:namespace:sa-name

# Test in pod kubectl exec pod-name -n namespace -- curl -s -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default/api/v1/namespaces/namespace/pods

# Verify role binding kubectl describe rolebinding binding-name -n namespace ```

Check effective permissions:

bash
# List all permissions for identity
kubectl auth can-i --list -n namespace --as=system:serviceaccount:namespace:sa-name

Common RBAC Permission Errors

ErrorCauseSolution
Forbidden on podsNo role for podsCreate Role with pods resource
Forbidden on deploymentsWrong API groupUse apiGroups: ["apps"]
Forbidden cross-namespaceRole is namespace-scopedUse ClusterRole
Forbidden for execMissing pods/execAdd pods/exec subresource
Forbidden for logsMissing pods/logAdd pods/log subresource
ServiceAccount token invalidWrong SA in podSet correct serviceAccountName
User cannot access clusterNo ClusterRoleBindingCreate binding for user/group

RBAC Best Practices

Use namespace-scoped Roles for most permissions. Create dedicated service accounts for applications. Avoid overly broad permissions (limit verbs/resources). Use ClusterRoles sparingly, only when necessary. Document RBAC requirements for applications. Audit RBAC regularly for unnecessary permissions. Use aggregated roles for standard permissions sets.

RBAC permission denied errors require checking who (subject) lacks what (role/binding). Create the appropriate Role/ClusterRole with correct resources and verbs, then bind it to the subject needing access.

  • [Fix Envoy Rate Limit Configuration with envoyproxy/ratelimit](envoyproxy-ratelimit-configuration-guide)
  • [Fix Fix Argocd App Not Syncing Issue in Kubernetes](fix-argocd-app-not-syncing)
  • [Fix Fix Argocd Sync Conflict Issue in Kubernetes](fix-argocd-sync-conflict)
  • [Fix ArgoCD Sync Timeout](fix-argocd-sync-timeout)
  • [How to Fix Cilium Identity Exhaustion and Endpoint Allocation Failed](fix-cilium-identity-exhaustion)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Kubernetes RBAC Permission Denied Error", "description": "Learn how to fix Kubernetes RBAC permission denied errors including role configuration, binding issues, and service account permissions.", "url": "https://www.fixwikihub.com/fix-kubernetes-rbac-permission-denied", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-18T20:48:25.436Z", "dateModified": "2025-11-18T20:48:25.436Z" } </script>