Cases3 cases
1 to 3 of 3
IL-0183kubeadm's one-year leaf certificates expired, so kube-apiserver could not reach etcd, restarted in a loop and left the cluster unreachableckck8032026- Symptoms
The cluster could not be reached from outside. On the control plane node, sudo systemctl status kubelet showed TLS handshake errors such as "http: TLS handshake error from 101.198.0.183:19517: tls: client requested unsupported application protocols" and "http: TLS handshake error from 101.198.0.172:36328: tls: client offered only unsupported versions: [302 301]".
- Trigger
The leaf certificates that kubeadm had generated for the cluster, valid for one year by default, expired at 2026-02-20 16:16 UTC.
- Root cause
- Component
- Contributing factor
- Detection
The author could not connect to the cluster from outside and went to the control plane node to read the kubelet logs.
- Remediation
- renewed all expired certificates with sudo kubeadm certs renew all
- restarted containerd and the kubelet so the static control plane pods restarted with the new certificates
- copied the renewed /etc/kubernetes/admin.conf to $HOME/.kube/config
- Lessons
A kubeadm cluster stops working one year after its leaf certificates were issued unless they are renewed. The first errors seen may be TLS handshake failures or a flag error that does not mention certificates; the decisive message is the x509 expiry in the kube-apiserver log for its connection to etcd. The author recommends checking expiry with kubeadm certs check-expiration and renewing from 30 days before. kubeadm upgrade apply renews the certificates too, so a cluster upgraded at least once a year avoids the problem; a cluster run for a long time without upgrades can renew from cron, for example with 0 3 1 1 * root kubeadm certs renew all && systemctl restart kubelet in /etc/cron.d/kubeadm-cert-renew.
IL-0113The managed GKE control plane of Webhook Relay's main cluster failed because its API server certificates had never been rotated, and a manual credential rotation reported success without taking effectWebhook Relay2022- Symptoms
At 12:00 EST the health check system reported that the backend APIs, the frontend and the tunnels in the EU region were down. The team first took it for a transient error, such as an interrupted client request or a server evicted for memory or CPU pressure, but the main dashboard was offline as well.
- Root cause
- Component
- Contributing factor
- Detection
The health check system sent a notification that the service was down; the team then found the main dashboard offline.
- Remediation
- recreated the node pools by hand after the credential rotation failed to recreate them
- duplicated the main cluster's services into a newly created GKE cluster
- deleted the Kubernetes Service records in the old cluster so its load balancers could be attached to the new cluster
- detached the StatefulSet from the old cluster and switched all writes to the main disk
- exported the data from the temporary ClickHouse instance and inserted it into the main instance
- Action items
- Change the deployment manifests so services can be switched between clusters quickly without a complicated persistent disk migration
- Lessons
Recovery of existing infrastructure needs a time limit. Throughout the outage the old cluster looked about to recover, and the reluctance to give up on the salvage effort kept the team from starting over with a new cluster much sooner, which would have been the right call. On older GKE clusters, check the validity of the cluster CA certificate, for example by decoding masterAuth.clusterCaCertificate from gcloud container clusters describe and reading it with openssl x509. GKE's multiple availability zones made no difference in this failure.
IL-0184JupyterHub's KubeSpawner could not create containers and kubectl was refused because the API server and other internal certificates of a kubeadm cluster had expireddbhang2021- Symptoms
KubeSpawner, which starts JupyterHub user containers on Kubernetes, failed to create containers with an error the author had never seen, saying an SSL certificate had expired.
- Root cause
- Component
- Contributing factor
- Detection
KubeSpawner failed to create a container and logged an SSL certificate verification error.
- Remediation
- checked certificate expiry with kubeadm alpha certs check-expiration
- moved the old certificates and /etc/kubernetes/*.conf files to a backup directory
- regenerated all certificates with kubeadm init phase certs all
- regenerated the kubeconfig files with kubeadm init phase kubeconfig all
- copied /etc/kubernetes/admin.conf to ~/.kube/config and restarted kubelet
- restarted the kube-system containers with docker restart so they picked up the new credentials
- Lessons
kubeadm clusters run on certificates that expire, and when the API server certificate expires kubectl cannot be used to fix it, so renewal has to happen on the control plane node with kubeadm. After renewal, the kubeconfig files and the running control plane containers must also pick up the new certificates, or kubectl returns Unauthorized.
These 3 cases involve Kubernetes API server and kubelet. kubegap audits a Kubernetes cluster for gaps like these, read-only, from Claude Code or Codex; its checks cite public reports like the ones in this library.
By root cause1
Certificate or credential expiry3 cases
- Component
- Contributing factor
- Organisation
IL-0183kubeadm's one-year leaf certificates expired, so kube-apiserver could not reach etcd, restarted in a loop and left the cluster unreachableckck8032026IL-0113The managed GKE control plane of Webhook Relay's main cluster failed because its API server certificates had never been rotated, and a manual credential rotation reported success without taking effectWebhook Relay2022IL-0184JupyterHub's KubeSpawner could not create containers and kubectl was refused because the API server and other internal certificates of a kubeadm cluster had expireddbhang2021