kubectl "You must be logged in to the server (Unauthorized)" in CI - Fix it
The connection reached the API server, but authentication failed: the server returned HTTP 401. The kubeconfig token, client certificate, or exec-plugin credential is absent, expired, or not accepted for this cluster.
What this error means
A kubectl apply, kubectl get, or kubectl rollout step in CI stops with error: You must be logged in to the server (Unauthorized). The same command may work locally where the kubeconfig holds fresh credentials.
error: You must be logged in to the server (Unauthorized)Common causes
An expired or short-lived token
A bearer token baked into the CI secret has expired, or an exec-plugin (cloud IAM) token was minted for a window that elapsed before the step ran.
The wrong or empty credential
The kubeconfig has no users[].user.token/cert, or it points at a service account whose token was revoked or never granted access to this cluster.
How to fix it
Re-fetch fresh cluster credentials in the job
- Generate the kubeconfig at the start of the job from the cloud provider, not from a stale committed file.
- Confirm the credential is current with a lightweight call before deploying.
- For long jobs, refresh the token close to the deploy step so it does not expire mid-run.
aws eks update-kubeconfig --name prod --region us-east-1
kubectl auth whoami
kubectl apply -f k8s/Verify the token actually reaches kubectl
A masked-but-empty secret produces an anonymous request. Echo the kubeconfig path and confirm the user entry is populated (never print the token itself).
echo "KUBECONFIG=$KUBECONFIG"
kubectl config view --minify -o jsonpath='{.users[0].name}'How to prevent it
- Mint credentials inside the job rather than storing a static token that ages out.
- Run
kubectl auth whoamias a fast pre-flight check before the deploy. - Prefer short-lived OIDC/exec-plugin auth over long-lived static tokens.