Incident Library
Applied filters FactorNo alert on limitDomainKubernetesClear allEvery case under the filters, with no sentence; newest first.
Suggested filters Search, and the values found in your words appear here.

Graph

  • Root cause
  • Component
  • Symptom
  • Contributing factor
  • Case

Cases19 cases

14 to 18 of 19

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

  2. Symptoms

    Shortly after a round of changes, loveholidays saw connectivity problems and raised error rates on its aggregation service. The service is a proxy between two other services of more than 100 instances each, handles over 10,000 requests per second continuously and can spike to four times that.

    Trigger

    Three changes together: a change in service architecture, halving the RAM of the nodes that run the aggregation service, and sharding a downstream service, which doubled the number of connections to track.

    Root cause
    Component
    Contributing factor
    Detection

    Rising error rates and climbing connection reset errors in HAProxy, then node_exporter conntrack metrics compared with their limit.

    Remediation
    • moved the aggregation service to nodes with more RAM
    • limited the number of aggregation service pods per node
    Action items
    • Alert when conntrack table use goes above 75%, with (node_nf_conntrack_entries / on (pod) node_nf_conntrack_entries_limit / on (pod) group_right kube_pod_info) > 0.75
    Lessons

    The conntrack limit is tied to node memory, so resizing a node pool silently resizes the connection table, and on GKE the ratio did not match the commonly cited formula. A high-traffic proxy on small nodes can exhaust it, and the symptoms are connection resets and timeouts, so conntrack use needs its own metric and alert.

  3. Symptoms

    Overnight into 26 March 2019 (PDT), every Prow test job that needed a GCP project from Boskos, the Kubernetes test-infra service that hands out GCP projects to test jobs, failed. The required job pull-kubernetes-e2e-gce failed on every run, so no pull request could be merged in kubernetes/kubernetes for just over nine hours, and other projects saw similar failures.

    Trigger

    At 23:04 PDT the node running the only Boskos pod was drained to be replaced with a 1.13 node during the upgrade of the Prow clusters from Kubernetes 1.11 to 1.13. The replacement pod started from the StatefulSet's current spec, which named a newer Boskos image containing the bug.

    Root cause
    Component
    Contributing factor
    Detection

    Users reported the failure on GitHub at 02:50 and on Slack at 05:16 and 06:27, and an engineer saw the Slack reports on waking at 07:16. The Boskos monitoring dashboard showed the failure, but no alert caught it.

    Remediation
    • Built and deployed a new Boskos image with the bug fixed
    • Cleaned up the GCP projects that had been left open
    Action items
    • Change the Boskos configuration so that deployments actually take effect (#11956)
    • Automate Boskos deploys (#11957)
    • Improve alerting on Boskos status (#11953)
    Lessons

    The write-up lists what went poorly: a ten-hour upgrade was started shortly after 17:00 when on-call coverage ended at 18:00; deployments were not checked to confirm that something had actually rolled out; the Boskos StatefulSet was not set up to perform updates, so changing its spec left the old pod running; the December change appears never to have been tested; and Boskos was deployed by hand, unlike most of Prow, which left more room for error. Once people were available, the problem was fixed quickly.

  4. Symptoms

    The NU.nl development team got reports that several services on one of its Kubernetes clusters behaved erratically: occasional error pages, slow responses and timeouts. The affected services were mostly internal tools and dashboards.

    Trigger

    A new ElastAlert rule, deployed shortly before from the command line, that fired if the Cloudfront-* Elasticsearch indexes stopped receiving documents; those indexes take a few million requests per hour, and the rule made ElastAlert's memory grow without bound.

    Root cause
    Component
    Contributing factor
    Detection

    Users reported error pages, slow responses and timeouts from several services; no alert fired.

    Remediation
    • terminated the NotReady nodes one by one so the auto-scaling group replaced them (the new nodes also went NotReady, but Prometheus and Grafana landed on a stable node)
    • found the ElastAlert pods' memory growth on the Grafana pod memory dashboard
    • fixed the ElastAlert problem that caused the memory growth
    Action items
    • Define alerts on resource usage such as CPU, memory and disk space
    • Keep researching an alerting strategy that combines Elasticsearch, Prometheus Alertmanager and New Relic
    • Consider exporting metrics out of the cluster and running Grafana outside it, on EC2 or a separate Kubernetes cluster
    • Either visualise the important metrics in the ELK stack or make Prometheus and Grafana more available, and improve the metrics strategy
    • Set resource limits for ElastAlert through the Helm values
    • Configure namespaces with default memory requests and limits
    • Isolate customer-facing workloads from build, logging and monitoring workloads (a dedicated node group, or later a separate tools cluster)
    • Deploy everything through automation such as Jenkins pipelines, and consider a GitOps approach
    • Deploy through a pipeline that includes a smoke test step
    • Make Kubernetes and cloud infrastructure work part of the team's sprints, picked up by all team members while pairing with more experienced members, and hold workshops that go deep into specific topics
    Lessons

    Fixing the root cause covers only a small part of what an incident can teach; the chain of smaller failures around it is where most of the learning is. A pod without a memory limit can take whole nodes down, so limits need defaults at the namespace level. Monitoring that runs inside the cluster it watches goes blind with it. Changes installed by hand from the command line leave the rest of the team without a record of what changed.

  5. Symptoms

    On Saturday 8 July 2018 at about 18:30 CEST, the launch success rate of mybinder.org dropped to zero and stayed there. Suspicious behaviour was first reported on Gitter at 22:48, more than four hours later.

    Root cause
    Component
    Contributing factor
    Detection

    Suspicious behaviour was reported on Gitter at 22:48 CEST, more than four hours after launch success dropped to zero; no downtime notifications were set up.

    Remediation
    • Deleted user pods older than four hours with the delete-pods.py script
    • Culled pods of the most-used images, such as ipython-in-depth, more aggressively
    • Restarted the Hub pod after about 600 pods were culled, which brought launches back to normal
    • Cordoned some of the extra nodes so the autoscaler could reclaim them
    • Ran manual max-age culling the next morning, letting the cluster scale back to 3 nodes
    Action items
    • Set up notifications of downtime
    • Automate cluster scale-down
    • Document the downtime recovery steps so every team member knows them
    • Fix KubeSpawner's failure to delete pods when the pod reflector fails
    • Make KubeSpawner more robust to pod reflector failure
    • Refactor the event reflector into a single reflector instead of one per pod
    • Detect a likely unhealthy Hub state and restart the Hub without manual intervention
    Lessons

    The delete-pods.py script was useful for bulk-deleting old pods, and once the problem was noticed the cluster was healthy within a few minutes. The outage lasted five hours before anyone noticed because no downtime notifications existed, and scaling the cluster back down still took several manual steps of cordoning and draining nodes.

Check your cluster for this

These 19 cases involve Node pool and JupyterHub. 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 cause6

Dependency failure1 case

Organisation
  1. IL-0133 A storm shut down cooling at Nebius's us-central1 data center, and a disk hot-plug bug kept Managed Kubernetes control planes down for hours after power returned
    Nebius2026

Configuration change3 cases

  1. IL-0246 New pods on Adyen's big data Kubernetes nodes could not start, failing with "Cilium API client timeout exceeded"
    Adyen2026
  2. IL-0019 An EKS Terraform module upgrade shrank node root disks from 100 GB to 20 GB and image pulls failed with no space left on device
  3. IL-0035 Worker nodes went NotReady after a new ElastAlert rule without memory limits used up node memory
    NU.nl2019

Capacity exhaustion9 cases

  1. IL-0470 Buildkite notifications were delayed after Prometheus storage filled and EKS notification workers could not autoscale
  2. IL-0465 IONOS Container Registry image pushes and pulls failed with 504 Gateway Timeout
  3. IL-0100 PostHog's feature flags pods were packed onto Kubernetes nodes that were too small for their CPU requests, and CPU saturation above 90% caused three outages in ten days through Redis overload, connection pool exhaustion and slow queries
  4. IL-0042 Application logs stopped reaching Elasticsearch and OpenSearch for hours and were lost when OpenSearch ran out of disk space
  5. IL-0043 Application logs missing in Kibana after a newer Fluent Bit version changed its chunk drop strategy
  6. IL-0016 Prometheus on the live cluster ran out of memory and was OOMKilled, and the monitoring node it ran on went NotReady
  7. IL-0500 UToronto JupyterHub logins and server starts returned 500 errors when the hub's sqlite database disk filled up
    2i2c2022
  8. IL-0013 The conntrack table filled up on downsized GKE nodes and a high-traffic aggregation proxy saw climbing connection resets
  9. IL-0503 mybinder.org launches failed after a GKE node ran out of memory and its nginx-ingress proxy pod crash-looped

Faulty deployment3 cases

  1. IL-0020 During an EKS 1.30 upgrade the descheduler tried to reschedule every pod on the cordoned nodes at once and production workloads went down
  2. IL-0530 Virtual router controllers in us-central1 ran out of memory in a loop, cutting networking for new and migrated VMs
  3. IL-0467 Boskos crash-looped after a node drain started it from a buggy StatefulSet image, failing Kubernetes PR jobs for 9 hours

Software defect2 cases

  1. IL-0077 EKS cluster went read-only for over seven hours after Kyverno ephemeralreports filled the etcd database past its size limit
  2. IL-0504 mybinder.org launches failed for about five hours as undeleted user pods piled up and filled the cluster

Certificate or credential expiry1 case

Organisation
  1. IL-0184 JupyterHub's KubeSpawner could not create containers and kubectl was refused because the API server and other internal certificates of a kubeadm cluster had expired
    dbhang2021