Kubernetes Error Guide: 'no such file /var/run/secrets/.../token' ServiceAccount Token Not Mounted
Fix pods that cannot authenticate to the API: 'open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file' from automountServiceAccountToken false or a missing projected token.
- #kubernetes
- #troubleshooting
- #errors
- #serviceaccount
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Exact Error Message
error: open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory
In-cluster client libraries report the same root cause in different words, for example unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined or serviceaccounts "default" is forbidden after the token is absent and the pod falls back to anonymous access.
Overview
Every pod that talks to the Kubernetes API from inside the cluster authenticates with a ServiceAccount token. By default the kubelet projects that token, along with the cluster CA and namespace, into each container at /var/run/secrets/kubernetes.io/serviceaccount/. In-cluster client libraries read the token file automatically to build their API configuration.
This error means the token file is not there. Either the pod was told not to mount it (automountServiceAccountToken: false), the projected-token volume was removed or overridden, or the ServiceAccount the pod references does not exist. Without the token, any in-cluster API call is unauthenticated and fails, and code that opens the file path directly errors with no such file or directory.
Symptoms
- An application that calls the Kubernetes API logs
no such file or directoryfor the token path on startup. kubectl execinto the pod shows theserviceaccountdirectory missing or lacking atokenfile.- API calls from the pod return
Unauthorizedorforbidden: User "system:anonymous". - The pod otherwise starts and runs; only its API access is broken.
Common Root Causes
1. automountServiceAccountToken is set to false
Setting this to false on the pod spec or on the ServiceAccount stops the kubelet from mounting the token, so the file never appears.
2. The referenced ServiceAccount does not exist
If serviceAccountName points at a name that is not in the namespace, the kubelet cannot project a token for it.
3. A volume or volumeMount overrides the projected path
Mounting an emptyDir or another volume at /var/run/secrets/kubernetes.io/serviceaccount shadows the automatically injected token volume.
4. Security tooling stripped the token
Admission controllers, PodSecurity policies, or hardening tools sometimes remove the projected token volume to reduce credential exposure.
5. Expired bound token not refreshed
With bound service account tokens, a container that caches the token but never re-reads the rotating file may see auth failures even when the file exists; a genuinely missing file is the stricter case.
Diagnostic Workflow
Step 1: Check whether the token file exists in the pod
kubectl exec <pod> -- ls -l /var/run/secrets/kubernetes.io/serviceaccount/
A missing token, ca.crt, or namespace file confirms the projection is absent.
Step 2: Inspect the pod’s automount setting
kubectl get pod <pod> -o jsonpath='{.spec.automountServiceAccountToken}'
An explicit false here (or on the ServiceAccount) is the direct cause.
Step 3: Confirm the ServiceAccount exists
kubectl get serviceaccount <name> -n <namespace>
If it is missing, the pod references a name that was never created.
Step 4: Look for a volume overriding the token path
kubectl get pod <pod> -o jsonpath='{.spec.volumes}' | tr ',' '\n'
Check for any volume mounted at the serviceaccount path.
Step 5: Verify the token actually authenticates
kubectl exec <pod> -- sh -c \
'curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/api'
Step-by-Step Resolution
- Re-enable automounting where the workload genuinely needs API access. Set it on the pod spec so it takes precedence:
spec:
automountServiceAccountToken: true
serviceAccountName: my-app
- Create the ServiceAccount if it is missing:
kubectl create serviceaccount my-app -n my-namespace
Then reference it with serviceAccountName: my-app and restart the pod.
-
Remove any overriding volume that shadows
/var/run/secrets/kubernetes.io/serviceaccount. Delete the conflictingvolumeMountso the kubelet’s projected volume is used. -
If you need a token but the platform strips the default, project one explicitly:
volumes:
- name: sa-token
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 3600
audience: api
Mount it and point your client at that path.
- Grant the ServiceAccount the RBAC it needs so that once the token is present, calls are authorized:
kubectl create rolebinding my-app-view \
--clusterrole=view --serviceaccount=my-namespace:my-app -n my-namespace
- Restart and confirm the token is mounted and working:
kubectl rollout restart deployment <deployment> -n my-namespace
kubectl exec <new-pod> -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | head -c 20
Seeing token bytes confirms the projection is restored.
Prevention
- Only set
automountServiceAccountToken: falseon workloads that never call the API, and be explicit about which ones do need it. - Give each application its own ServiceAccount with least-privilege RBAC rather than relying on
default. - Avoid mounting volumes at the reserved serviceaccount path; pick a different mount point for app data.
- Use bound, audience-scoped projected tokens with a sensible
expirationSecondsand ensure clients re-read the rotating file. - Add a startup check in your app that verifies the token path exists and fails fast with a clear message.
Related Errors
serviceaccounts "default" is forbidden: User "system:anonymous"— the pod fell back to anonymous because no token was mounted.Unauthorizedfrom in-cluster API calls — a present but invalid or expired token.pods "x" is forbidden: ... cannot get resource— the token authenticated but lacks RBAC permissions.unable to load in-cluster configuration— the client library could not find the token or the service env vars.
Frequently Asked Questions
Where should the token file be? In-cluster it lives at /var/run/secrets/kubernetes.io/serviceaccount/token, alongside ca.crt and namespace. If that file is missing, the kubelet did not project the token for this pod.
Why would automountServiceAccountToken be false? It is a hardening choice to avoid handing API credentials to workloads that do not need them. Set it back to true only for pods that genuinely call the API.
Does using a custom ServiceAccount fix this? It helps only if that ServiceAccount exists and automounting is enabled. Create the account, reference it by name, and bind least-privilege RBAC to it.
My token file exists but calls still fail. Why? A present token that returns Unauthorized usually means it is expired or the ServiceAccount lacks RBAC. Check the token’s audience and add a suitable RoleBinding. Prompt templates for RBAC and workload identity live in the DevOps AI prompt library.
How do bound tokens differ from legacy secret tokens? Bound tokens are short-lived, audience-scoped, and rotated in place by the kubelet, so clients must re-read the file rather than caching it once. Legacy non-expiring secret tokens are discouraged. For more, see the Kubernetes & Helm guides.
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.