- Go
- Exact text checked with the real tool
x509: certificate has expired or is not yet valid
Also seen in: kubectl, Kubernetes, Docker, Terraform, Helm, Prometheus, other Go programs
In one sentence
A certificate is outside its validity dates by this machine's clock; the end of the message says which. In Kubernetes, the cluster's own certificates have often expired.
Where you see it
In programs written in Go: kubectl and other Kubernetes tools, the Docker client and daemon, Terraform, Helm and your own Go services. A Go HTTP client prints:
Get "https://api.example.com/": tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2026-10-20T02:08:22Z is after 2026-04-01T00:00:00Z
kubectl prints the same reason, first in a few log lines and then as a summary:
E1020 02:08:44.981559 3859 memcache.go:381] "Couldn't get current server API group list" err="Get \"https://203.0.113.10:6443/api?timeout=32s\": tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2026-10-20T02:08:44Z is after 2026-04-01T00:00:00Z"
Unable to connect to the server: tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2026-10-20T02:08:44Z is after 2026-04-01T00:00:00Z
The text comes from Go’s crypto/x509 verify.go. Go 1.20 added the tls: failed to verify certificate: prefix; since Go 1.14 the message ends with the two times. Docker adds its own prefix, such as Error response from daemon:.
What it means
Every certificate has a validity period. Go checks each certificate on the path against the machine’s clock, and the end of the message says what it found:
current time … is after …: the certificate expired at the second time shown;current time … is before …: the certificate is not valid yet until the second time, which usually means this machine’s clock is behind.
Compare the first time with the real time. If the first time is wrong, fix the clock; if it is right, renew the certificate.
Likely causes
The server’s certificate expired
Confirm what the server sends:
openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -dates
Fix: renew the certificate, install it with its full chain, and reload the service. For a private Docker registry, also check the CA and client certificates in /etc/docker/certs.d/<registry>/ on each client. Public TLS certificates may be valid for at most 200 days since 15 March 2026, and for at most 47 days from 15 March 2029: automate renewal (How to check when a certificate expires, and monitor it).
The Kubernetes cluster’s own certificates expired
Clusters built with kubeadm have their own private CA. “Client certificates generated by kubeadm expire after 1 year”, and kubeadm renews them automatically during control-plane upgrades (Kubernetes documentation). A cluster that was not upgraded for a year stops answering kubectl with exactly this error. Confirm on a control-plane node:
sudo kubeadm certs check-expiration
Fix, following that page: renew on every control-plane node, restart the control-plane static Pods, and copy the new admin kubeconfig:
sudo kubeadm certs renew all
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
To restart a static Pod, move its manifest out of /etc/kubernetes/manifests/, wait about 20 seconds, then move it back. Your own kubeconfig may also hold an expired client certificate if it was copied from admin.conf long ago.
The certificate was renewed, but the old one is still served
Ingress controllers, load balancers and long-running Go services keep the certificate they loaded. Compare the served dates with the new file (openssl x509 -in tls.crt -noout -enddate), then reload or restart. In Kubernetes, check that the ingress uses the renewed Secret; see How to automate certificates in Kubernetes with cert-manager.
The machine’s clock is wrong
is before with a date in the future, or a current time that is clearly wrong, points to the client’s clock. Small devices without a clock battery, virtual machines restored from snapshots and containers on such hosts are typical. Fix: turn on time synchronisation (timedatectl status, then sudo timedatectl set-ntp true on systemd Linux).
Check yours
Paste the certificate (for a kubeconfig, decode client-certificate-data with base64 -d). The decoder shows the validity dates and how many days are left or overdue.
Learn why
- Anatomy of an X.509 certificate: the validity fields.
- Inventory, expiry and renewal: stopping expiry outages.
- Related: x509: certificate signed by unknown authority.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.