Kubernetes Error Guide: 'x509: certificate has expired or is not yet valid' Expired Certs
Fix 'x509: certificate has expired or is not yet valid' in Kubernetes: renew expired kubeadm 1-year certs, fix clock skew, and stop apiserver/kubelet TLS failures.
- #kubernetes-helm
- #troubleshooting
- #errors
- #tls
Exact Error Message
When a TLS peer presents a certificate that is outside its validity window, the Go TLS stack rejects the handshake with a time-stamped error. kubectl and component logs show it like this:
Unable to connect to the server: x509: certificate has expired or is not yet valid: current time 2026-06-28T09:14:55Z is after 2026-06-21T08:02:31Z
A “not yet valid” variant (clock skew, certificate issued for the future) reads:
x509: certificate has expired or is not yet valid: current time 2026-06-28T09:14:55Z is before 2026-06-29T00:00:00Z
In the kubelet or apiserver log it appears mid-handshake:
E0628 09:14:55.220317 1 authentication.go:63] "Unable to authenticate the request" err="x509: certificate has expired or is not yet valid: current time 2026-06-28T09:14:55Z is after 2026-06-21T08:02:31Z"
The two timestamps are the whole story: current time versus the certificate’s NotBefore/NotAfter boundary it violated.
What the Error Means
This is not a trust-chain problem. The certificate may be signed by a perfectly valid CA — the failure is purely about time. Every X.509 certificate has a validity window (NotBefore … NotAfter). The Go verifier compares the system clock against that window and rejects the cert if the clock is after NotAfter (expired) or before NotBefore (not yet valid).
In Kubernetes this overwhelmingly means kubeadm’s one-year control-plane certificates expired. kubeadm issues apiserver, apiserver-kubelet-client, front-proxy, and etcd certs with a 365-day lifetime. Clusters that are not upgraded at least annually hit the wall exactly one year after kubeadm init, and the apiserver stops trusting (or being trusted by) its peers — kubectl breaks cluster-wide.
The “not yet valid” form is almost always clock skew: a node’s clock is wrong (NTP failure, VM time drift) so a currently-valid certificate looks future-dated. Distinguishing the two cases is just reading whether current time is after or before the boundary.
Common Causes
- Expired kubeadm certificates — the 1-year control-plane certs lapsed because the cluster was not upgraded/renewed.
- Expired kubelet client/serving certs — kubelet certificate rotation disabled or broken, so its cert aged out.
- Clock skew (NTP failure) — a node’s clock is wrong, making valid certs look expired or not-yet-valid.
- Expired etcd peer/server certs — etcd TLS certs lapsed, breaking apiserver-to-etcd.
- Stale kubeconfig — an embedded client cert in
~/.kube/configoradmin.confexpired. - Wrong timezone / RTC — a host with a misconfigured hardware clock after reboot.
How to Reproduce the Error
You do not need to wait a year. Generate a short-lived certificate and try to use it past expiry:
# Create a cert that is valid for 10 seconds, then let it lapse
openssl req -x509 -newkey rsa:2048 -nodes -keyout /tmp/k.key \
-out /tmp/k.crt -days 0 -subj "/CN=test" 2>/dev/null
sleep 12
openssl verify /tmp/k.crt
error /tmp/k.crt: verification failed
C0628 ... x509: certificate has expired or is not yet valid
For clock skew, set a node’s clock forward past a real certificate’s NotAfter and any TLS call to the apiserver immediately fails with the same message.
Diagnostic Commands
# kubeadm's built-in expiry table — the fastest answer on control-plane nodes
kubeadm certs check-expiration
# Read NotBefore/NotAfter directly from a cert on disk
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates -subject
# Inspect the cert embedded in a kubeconfig
grep client-certificate-data ~/.kube/config | awk '{print $2}' | base64 -d | openssl x509 -noout -dates
# Check what the live apiserver is actually serving
echo | openssl s_client -connect <APISERVER>:6443 2>/dev/null | openssl x509 -noout -dates
# Verify node clock and NTP sync (rules in/out skew)
timedatectl status
journalctl -u kubelet --no-pager | grep -i 'x509\|certificate has expired'
kubeadm certs check-expiration is the single most useful command on a kubeadm cluster — it lists every managed certificate and its remaining validity. Always confirm timedatectl shows the clock synchronized before blaming the certificates.
Step-by-Step Resolution
1. Decide: expired or skew? Read the message. current time ... is after <NotAfter> = genuinely expired. current time ... is before <NotBefore> = clock is wrong. If timedatectl shows the clock is off, fix time first.
2. Fix clock skew. Re-enable and sync NTP, then retry — no cert changes needed:
timedatectl status # confirm "System clock synchronized: yes"
If the clock was wrong, valid certs immediately start working again once time is correct.
3. Renew kubeadm certificates. On each control-plane node, renew all managed certs:
kubeadm certs renew all
kubeadm certs check-expiration # confirm new 1-year NotAfter dates
4. Restart the control-plane components. Static pods must reload the new certs. Move the manifests out and back, or restart the kubelet so apiserver/controller-manager/scheduler/etcd pick up the renewed files.
5. Refresh the admin kubeconfig. If admin.conf/~/.kube/config had an expired client cert, regenerate it:
kubeadm kubeconfig user --client-name=admin > /tmp/admin.conf # read-only generation
Then replace your kubeconfig and verify kubectl get nodes works.
6. Fix kubelet cert rotation. If kubelet serving/client certs expired, ensure rotateCertificates: true and a working CSR approver so they auto-renew going forward.
Prevention and Best Practices
- Upgrade clusters at least once a year;
kubeadm upgrade applyrenews control-plane certs as a side effect. - Alert on
kubeadm certs check-expiration(or a cron exporting NotAfter) well before the 1-year mark — 30+ days of lead time. - Enforce NTP on every node and alert when
timedatectlreports the clock unsynchronized; skew breaks TLS silently. - Enable kubelet certificate rotation so node certs never reach expiry.
- Treat certificate renewal as a scheduled operational task, not an incident response.
- Keep a documented runbook for
certs renew all+ component restart so recovery is fast. More TLS guidance in our Kubernetes & Helm guides.
Related Errors
- x509: certificate signed by unknown authority — a trust-chain failure, not a time failure; distinct root cause.
- kubelet certificate rotation CSR pending — stuck rotation that leads to eventual expiry.
- node not ready — a downstream effect when kubelet TLS fails.
Frequently Asked Questions
How is this different from “signed by unknown authority”? Completely different. “Unknown authority” means the CA is not trusted — a chain/trust problem. “Has expired or is not yet valid” means the cert’s time window is violated even though the CA may be fully trusted. Read which message you got before choosing a fix.
Why did my whole cluster break at the same time? kubeadm issues control-plane certs with a 365-day lifetime from kubeadm init. If you never upgraded, they all expire within days of each other exactly one year later, taking down apiserver TLS cluster-wide.
kubectl says “not yet valid” — the cert is brand new. Why? Your client’s clock is behind the certificate’s NotBefore. This is clock skew. Sync NTP on the machine running kubectl; the certificate is fine.
Does kubeadm certs renew all cause downtime? Renewal itself is quick, but the control-plane static pods must restart to load the new certs, causing a brief apiserver blip. Do it node by node on HA control planes to avoid a full outage.
Will renewing certs change my CA? No. kubeadm certs renew reissues leaf certificates from the existing CA, so client trust and kubeconfig CA data remain valid. Only the leaf certs and their expiry dates change.
Download the Free 500-Prompt DevOps AI Toolkit
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.