Skip to content
ssldays

Guide

Kubernetes API server certificate expired

kubectl fails when the Kubernetes API server TLS certificate is past notAfter. Check kubeadm or static-pod certs, renew the apiserver material, and verify handshakes on 6443.

Updated May 2, 2026 1,012 words

kubernetes api server certificate expired means the control plane presents a leaf past notAfter on port 6443—renew apiserver certs before chasing kubelet or CNI symptoms.

Platform engineers see this when kubectl dies mid-incident, CI deploy pipelines cannot apply manifests, and monitoring agents lose cluster access. The failure is on the API server listener, not on ingress certificates customers browse.

Client-side kubeconfig tricks rarely help: kubectl validates the server certificate chain during TLS. Fix what the apiserver actually serves, then re-run the same failing command.

First response

Capture the exact kubectl or client-go error, cluster endpoint hostname, and whether the failure hits every control-plane node. In the ticket, include kubectl cluster-info output with tokens redacted, openssl s_client against the API server host on port 6443, output of kubeadm certs check-expiration on each control-plane node for kubeadm clusters, and timestamps showing when automation last rotated control-plane material.

Do not rotate worker kubelet client certs first when the apiserver cert itself expired—that masks the root listener problem. Prove expiry on 6443 from a machine that uses the same DNS name as the production kubeconfig server URL field.

Escalations should cite openssl serial and notAfter before anyone edits RBAC, CNI versions, or node images. When kubernetes api server certificate expired clusters around GitOps or CI, the stale material is almost always on the HA API VIP or a single control-plane member still serving yesterday’s apiserver leaf.

See also Let's Encrypt certificate expired in Kubernetes for ingress TLS, and cert-manager not renewing when workload certs stall separately from the control plane. For a broader renewal runbook after dates are fixed, see fix an expired SSL certificate.

What this error means

The Kubernetes API server terminates TLS on 6443 or your configured secure port. During the handshake, the client verifies signatures, validity windows, and (for many setups) the server hostname against the certificate SANs.

When notAfter is in the past, verification fails before the Kubernetes API responds. Symptoms look like generic TLS errors—x509 certificate has expired, Unable to connect to the server, or webhook timeouts—because every controller and human operator shares the same broken trust anchor.

This is distinct from kubelet serving certificates or etcd peer TLS, though a sloppy rotation can break multiple components at once. Your openssl capture must name which process answered on which port.

In PKIX terms, kubectl and client-go treat the TLS Certificate message as authoritative. Expiry on any link in the path the client builds fails the handshake even if your ingress certificates on port 443 look healthy. Guides about kubernetes api server certificate expired still require reading dates on the leaf served on 6443, not on unrelated application Secrets.

Common causes

These patterns appear often during kubernetes api server certificate expired incidents. They explain why control-plane upgrades looked complete while kubectl still rejected the listener.

Missed kubeadm certificate renewal. Clusters built with kubeadm ship one-year or configurable apiserver certificates. Teams upgrade Kubernetes but skip kubeadm certs renew and kubeadm upgrade apply steps that refresh control-plane PEMs.

Manual static-pod edits. Apiserver manifests under /etc/kubernetes/manifests/ still mount old apiserver.crt after operators copied new files elsewhere on disk.

Load balancer in front of apiservers. HA setups terminate TLS on an external LB with its own cert while members hold different material. One expired member poisons round-robin health checks.

Clock skew on control-plane nodes. Large notBefore/notAfter mismatches against NTP drift trigger failures that resemble expiry; confirm with timedatectl after openssl proves dates.

Restored etcd snapshots without cert state. Disaster recovery brought back an old PKI directory while clients still expect the previous serial numbers.

Certificate distribution controllers lagging. Hosted distributions sync PKI to members on a schedule; one member can present expired material while peers already renewed.

Confirm from the outside

OpenSSL against the API server

APISERVER=api.example.com
echo | openssl s_client -connect "${APISERVER}:6443" -servername "${APISERVER}" 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer -serial

Use the same hostname your kubeconfig server entry references. For IP-only endpoints, match the SAN list the cert actually contains.

kubeadm expiration inventory

sudo kubeadm certs check-expiration

Focus rows labeled apiserver, apiserver-kubelet-client, and front-proxy-client. Expired apiserver rows confirm the control-plane listener problem.

kubectl with verbosity

kubectl version --v=6 2>&1 | grep -Ei 'certificate|x509|expired'

Save verbose TLS logs; they document which certificate the client rejected.

How to read the output

notAfter in the past on the leaf served on 6443 is sufficient to explain the outage. Compare subject and Subject Alternative Name entries with the DNS name in kubeconfig. Note issuer and serial before renewal so post-fix checks prove new material is live. If openssl shows valid dates but kubectl fails, inspect corporate proxies or split-horizon DNS before reissuing.

Fix checklist

  1. Confirm expiry on 6443 with openssl from off-cluster if possible.
  2. Back up /etc/kubernetes/pki or your PKI path before rotation.
  3. Run the supported renewal path: kubeadm certs renew apiserver and related certs per your distribution docs.
  4. Restart kubelet so static-pod apiserver picks up mounted certs, or follow your vendor’s rolling control-plane procedure.
  5. If an external LB terminates API TLS, renew and upload the certificate there too.
  6. Re-run kubectl get nodes without insecure-skip-tls-verify.
  7. Verify webhook and aggregation layers still trust the renewed front-proxy chain.
  8. Document new notAfter in change records and monitoring.

For managed Kubernetes on EKS, GKE, or AKS, control-plane TLS is operator-managed—open a provider ticket with openssl evidence rather than kubeadm steps on worker nodes.

After rotation, compare serial numbers from openssl against your incident-opening capture on every control-plane endpoint and the public VIP. Close the incident only when CI, human operators, and in-cluster controllers all complete TLS handshakes without bypass flags.

When to use automation

Ingress monitors miss 6443 unless you explicitly check the API endpoint. Automate live TLS probes against the same server URL kubectl uses, not only public website hostnames. A one-shot check on /check helps validate customer-facing certs; schedule separate monitors for the API FQDN.

Pair certificate expiry with RDAP on the domain that resolves to the API load balancer so DNS delegation does not block the next rotation window. Alerts at 30, 14, 7, and 1 day thresholds give time for maintenance windows on HA control planes. Services such as ssldays can watch those thresholds without replacing kubeadm or your cloud provider’s PKI workflow.

Frequently asked questions

Is insecure-skip-tls-verify acceptable?

Only for isolated debugging. Production automation and human access should validate the apiserver cert. Skipping verification exposes clusters to person-in-the-middle risk during exactly the window attackers watch.

Why do only some operators fail?

Split-horizon DNS or stale hosts files can send one laptop to a decommissioned apiserver IP still serving an old cert. Compare server URLs and openssl results across failing clients.

What about etcd expiry?

Expired etcd peer or client certificates cause different errors (database unavailable, leader election loss). Still run kubeadm certs check-expiration, but fix etcd and apiserver rows based on which port openssl shows stale dates.

After renewal, webhooks still timeout?

Aggregated API servers and admission webhooks may trust the old front-proxy CA bundle. Redistribute front-proxy-ca trust to webhook clients and restart controllers that cache TLS config.

See what the server presents right now

Free live certificate check — no signup.