<!-- https://pkizerotohero.com/errors/go-x509-certificate-expired/ | Markdown mirror of the HTML page | PKI Zero to Hero, by Duyutech BV -->

> Fix Go's x509: certificate has expired or is not yet valid in kubectl, Docker and Go apps: read the times, then renew the certificate or fix the clock.

Source: https://pkizerotohero.com/errors/go-x509-certificate-expired/ · Last reviewed: 2026-10-20

- 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.

[Check yours: Certificate decoder](https://pkizerotohero.com/tools/decoder/)

## 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:

```text
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:

```text
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](https://go.dev/src/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](https://pkizerotohero.com/handbook/glossary/#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:

```bash
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](https://pkizerotohero.com/guides/check-certificate-expiry/)).

### 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](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/)). A cluster that was not upgraded for a year stops answering kubectl with exactly this error. **Confirm** on a control-plane node:

```bash
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:

```bash
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](https://pkizerotohero.com/guides/kubernetes-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).

Warning

Why InsecureSkipVerify is a trap

`InsecureSkipVerify: true` in Go, `--insecure-skip-tls-verify` in kubectl and `insecure-registries` in Docker accept every certificate, including an attacker’s. For a cluster, that exposes your credentials to anyone in the path. Renew the certificate or fix the clock.

## Check yours

*Interactive tool: Certificate decoder (runs in the browser at [/tools/decoder/](https://pkizerotohero.com/tools/decoder/))*

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](https://pkizerotohero.com/handbook/x509-certificates/): the validity fields.
- [Inventory, expiry and renewal](https://pkizerotohero.com/handbook/certificate-lifecycle/): stopping expiry outages.
- Related: [x509: certificate signed by unknown authority](https://pkizerotohero.com/errors/go-x509-unknown-authority/).

**Early edition.** Checked against the standards; an independent expert review is in progress. Found a mistake? [Tell us](https://pkizerotohero.com/contact/?topic=content-error&page=/errors/go-x509-certificate-expired/).

Last reviewed 20 October 2026Edition 0.9

## Learn why it happens

- [Chapter 8: Anatomy of an X.509 certificate](https://pkizerotohero.com/handbook/x509-certificates/)
- [Chapter 19: Inventory, expiry and renewal](https://pkizerotohero.com/handbook/certificate-lifecycle/)

## Fix it step by step

- [How to check when a certificate expires, and monitor it](https://pkizerotohero.com/guides/check-certificate-expiry/)

## Everything on this topic

- [Lifecycle and automation](https://pkizerotohero.com/topics/lifecycle-and-automation/)
