Kubernetes projected service account token expiry time issue
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Projected service account tokens in Kubernetes are supposed to expire. That is the security improvement. The real issue appears when an application reads the token once at startup, keeps it in memory, and continues sending an old credential after Kubernetes has already rotated the mounted file.
Why Projected Tokens Behave Differently
Older clusters often mounted long-lived service account tokens from a secret. Those tokens were convenient, but they stayed valid for too long and increased the damage from a leak.
Projected tokens use the TokenRequest flow instead. The kubelet mounts a token file into the pod, that token has an expiration time, and Kubernetes refreshes the file before it expires. If your client rereads the file, the application keeps working. If it caches the token forever, you eventually see authentication failures.
That is why many expiry reports are really application reload bugs rather than Kubernetes bugs.
Configuring the Projected Volume
Here is a minimal pod manifest that requests a projected service account token:
The expirationSeconds value is a request, not an unlimited guarantee. The control plane can enforce a maximum lifetime. The audience also matters. A fresh token with the wrong audience can still be rejected.
Make the Application Rotation-Friendly
The safest application pattern is to read the mounted token file whenever you build an authenticated request. This Python example keeps the token handling simple:
If you use an official Kubernetes client with in-cluster configuration, check whether it already reloads the token from disk. Many client libraries do, so replacing them with a custom startup-time read is often a regression.
Cluster Settings That Influence Expiry
When the token still seems wrong, inspect the cluster settings. Issuer configuration, signing keys, accepted audiences, and maximum token lifetime all affect whether a projected token is valid.
Clock skew is another easy trap. If the node, API server, or external verifier has the wrong time, a perfectly healthy token can appear expired or not yet valid. Time drift often looks like random authentication noise until you compare clocks directly.
Debugging the Mounted Token
Start by watching the token file inside the pod. If the file timestamp changes over time, Kubernetes is rotating it. If your process still uses an expired token after that, the process is probably holding on to an old in-memory value.
It also helps to decode the JWT claims during debugging. The exp, iat, iss, and aud claims tell you whether the failure comes from true expiration, an issuer mismatch, or the wrong audience. Decode carefully and avoid dumping full tokens into production logs.
Common Pitfalls
The biggest mistake is reading the token once during application startup and storing it in a singleton. That pattern worked with long-lived secret tokens and breaks with projected ones.
Another issue is assuming Kubernetes must honor any expirationSeconds value you request. The control plane can shorten it.
Teams also copy the token into a different file during bootstrap. Kubernetes rotates the mounted token file, not the copied one, so the application keeps using stale data.
Summary
- Projected service account tokens are intentionally short-lived and rotate automatically.
- Expired-token errors usually come from applications caching the token instead of rereading the mounted file.
- The audience claim must match the service that verifies the token.
- Cluster settings and clock skew can make a healthy token appear invalid.
- Prefer in-cluster client behavior that already supports token rotation.

