ServiceAccount token not mounted: A pod expected in-cluster credentials and does not have them
An application that calls the Kubernetes API from inside a pod reads a token from a fixed path. If automounting is disabled or the ServiceAccount does not exist, that path is empty and every API call fails.
Applies to: All Kubernetes versions
What it means
By default, each pod gets its ServiceAccount's token projected into /var/run/secrets/kubernetes.io/serviceaccount/, along with the cluster's CA certificate and the namespace. In-cluster client libraries read those files automatically, which is how a pod authenticates without any configuration. When automountServiceAccountToken is false — set on the pod, or on the ServiceAccount, which applies to every pod using it — those files are absent and any API call fails at the client library, usually with a message about being unable to load in-cluster configuration. Disabling automounting is a sensible default for workloads that never talk to the API; it becomes a problem when a workload that does need it inherits the setting.
Most common causes
automountServiceAccountToken: falseset on the pod or on its ServiceAccount.- The named ServiceAccount does not exist in the namespace, so the pod cannot be admitted with it or gets no token.
- A policy or admission webhook removing the token mount.
- A volume mounted over
/var/run/secrets, hiding the projected token. - An application reading the token once at startup and never reloading it, so it fails after the token is rotated.
- A long-running client holding a token past its expiry, since projected tokens are time-limited.
How to diagnose it
- Check whether the files exist:
kubectl exec POD -- ls /var/run/secrets/kubernetes.io/serviceaccount/. - Check the setting on both the pod and the ServiceAccount — either can disable it:
kubectl get pod POD -o jsonpath='{.spec.automountServiceAccountToken}'and the same on the ServiceAccount. - Confirm the ServiceAccount exists:
kubectl get sa -n NAMESPACE. - Check for a volume mount covering that path in the pod spec.
- If failures start after a period of uptime, suspect token expiry and check whether the client reloads the file.
How to fix it
- Set
automountServiceAccountToken: trueon pods that need API access, which overrides a ServiceAccount-level default of false. - Create the ServiceAccount, and bind it to the roles the workload needs.
- Remove any volume mount shadowing the projected token path.
- Make the application re-read the token file rather than caching it. Official client libraries handle this; simple HTTP clients usually do not.
- Leave automounting disabled for workloads that never call the API — it removes a credential from a pod that has no use for it.
Notes
Bound ServiceAccount tokens expire and are rotated in place. An application that reads the token once at startup works perfectly for the first hour or so and then begins failing with authentication errors, which makes the cause look unrelated to how the token is read.
Related
- Unauthorized — The request was not authenticated
- Error from server (Forbidden) — RBAC denied the request
Sources
- Kubernetes documentation — Configure Service Accounts for Pods
- Kubernetes documentation — Managing Service Accounts
- Kubernetes documentation — Authenticating