Incident Library
Applied filters SymptomContainer crash loopFactorSingle point of failureDomainKubernetesClear 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

Cases5 cases

1 to 5 of 5

  1. Symptoms

    On 21 October 2025 at 21:45 UTC a change to timeout handling was deployed to the feature flags service, and two minutes later automated monitoring reported higher error rates. The change was rolled back by 21:49, but error rates stayed high: about 38% of flag evaluation requests in the US datacenter returned errors. At 22:30 Redis metrics showed memory exhaustion on ElastiCache, at 22:35 Postgres connections spiked, and at 22:45 the team found a massive data transfer from Postgres into Redis. The main PostHog application was affected as well, because it shares the Redis instance with the flags service.

    Trigger

    On 21 October a deployment meant to reduce timeout errors (PR #39821); on 24 October the deployment of IP-based rate limiting (PR #40074) that saw all traffic as coming from the load balancer's IP; on 28 October an unrelated routine deployment that rolled the feature flag pods in the US region.

    Root cause
    Component
    Contributing factor
    Detection

    On 21 October automated monitoring detected higher error rates two minutes after the deploy. On 24 October no alert existed for 429 errors, and the team learned of the incident from customer reports that began at 18:10 UTC, a 62-minute detection delay. On 28 October on-call received a high error count alert. On 29 October the incident was reported with higher error rates and latency. No alert existed for CPU pressure, so the CPU saturation behind all three incidents was not seen directly.

    Remediation
    • rolled back the timeout handling change within 2 minutes on 21 October, which did not stop the errors
    • throttled connections and Redis writes on 21 October
    • halted the rollout on 28 October, scaled the US flags pods to zero until Redis recovered, then scaled them back gradually
    • rolled back hardware changes on 30 October at 00:03 UTC, which removed most errors but not the latency
    • increased the pod resource requests and adjusted the Kubernetes fleet size so fewer pods ran on each node
    • added retry limits to Envoy between the load balancer and the service
    • moved database connection timeouts and other critical settings to runtime configuration and raised the timeout values
    • added per-node and per-pod CPU alerts at 80% sustained for 5 minutes that page on-call
    Action items
    • Form a strike team from the flags, ingestion and infrastructure teams to review the application and infrastructure for remaining bottlenecks
    • Investigate separating the flags Redis instance from the application Redis instance
    • Before re-enabling ArgoCD sync, align the flags service chart configuration with the values in ArgoCD and define the deployment and Redis strategy
    • Make the feature flags team hard code-owners for flags-related code
    • Build a dashboard of key flag metrics with runbook links and update the feature flag runbooks
    • Add missing alerts on existing service and infrastructure metrics
    • Make readiness checks validate dependencies that degrade under load, for example by pinging the database
    • Rate-limit cache population so it cannot overwhelm Redis
    • Monitor connection pools with automatic throttling near exhaustion and limit concurrent connections
    • Build a production-scale load testing framework
    • Build progressive rollout infrastructure to limit blast radius
    • Document Postgres-to-Redis data flows and write runbooks for data transfer storms
    Lessons

    Nodes that are small relative to pod requests let the scheduler pack many pods on each node, and the resulting CPU saturation showed up three different ways: excessive parallelism, connection pool exhaustion and slow queries. Treating each symptom separately let the problem return; right-sizing the pods and nodes fixed all three. CPU must be alerted on from the start. Unbounded Envoy retries and unbounded cache population amplified the overload, and a Redis instance shared with the main application spread a flags problem to the main application. A rollback did not end the incident, because the data transfer and resource exhaustion it had started kept running.

  2. Symptoms

    Nodes that already existed kept running, but every new node, spot or standard, on either v1.32 or v1.33, failed to initialise and could not join the cluster. Spot nodes that were preempted and recreated never came back, so services degraded progressively: background workers on spot instances, reporting services and order allocation stopped completely, and the APIs on existing nodes kept answering but could not scale for load spikes.

    Trigger

    Google upgraded the GKE control plane from v1.32.x to v1.33.2 at the version deprecation deadline, although auto-upgrade was disabled on the node pools.

    Root cause
    Component
    Contributing factor
    Remediation
    • Created a new GKE cluster at v1.33, the version of the forced upgrade
    • Upgraded Istio to 1.27.1 for Kubernetes 1.33 compatibility
    • Updated the cert-manager configuration for Kubernetes 1.33
    • Migrated all production workloads to the new cluster and verified pod scheduling, DNS resolution, PVC mounting and external integrations
    • Decommissioned the broken cluster
    Action items
    • Configure all clusters to use the GKE stable release channel
    • Implement a separate management cluster for Argo CD, monitoring and other control components (Q4 2025)
    • Review spot instance usage for critical workloads and add on-demand fallback pools
    • Document the SRE upgrade procedure: management cluster first, production after a monitoring period of several days
    • Document a Kubernetes, Istio and cert-manager compatibility matrix
    • Create an automated upgrade testing pipeline
    • Reserve static IPs for quick migrations
    • Pin versions of Istio, cert-manager, CSI and DNS addons
    • Stay current with stable releases and regularly check GKE alerts and announcements to avoid deprecation deadlines
    Lessons

    GKE upgrades the control plane at a version's deprecation deadline even when auto-upgrade is disabled, so staying inside the supported version window is how to avoid a forced upgrade. A control plane upgrade can leave existing nodes healthy while every new node fails, and spot nodes that cannot rejoin after preemption turn this into cascading failures. Relying heavily on spot instances for critical workers turned a node join failure into a progressive outage. Kubernetes upgrades have to be planned together with dependent components such as Istio and cert-manager, and without a standby cluster on the same provider there was no immediate failover; the only recovery left was building a new cluster.

  3. Symptoms

    On Sunday 25 October 2020 the GoCardless API, dashboard, payment pages and partner integrations were all unavailable for 22 minutes, from 07:32 to 07:54 GMT. Automated monitoring paged the on-call engineer at 07:32, a minute after every request to the API had started failing because no healthy backend was left.

    Trigger

    At 07:22 the TLS certificate Vault was still serving expired. cert-manager had already renewed it, but Vault does not load a new certificate without a restart or a SIGHUP.

    Root cause
    Component
    Contributing factor
    Detection

    Automated monitoring detected the failing requests and paged the on-call engineer at 07:32. Certificate expiry monitoring existed for the Layer-7 load balancers but did not cover the TCP load balancer that Vault uses.

    Remediation
    • Forced cert-manager to recreate the Vault certificate
    • Restarted the Vault cluster by hand so it loaded the new certificate
    • Deleted some pods of critical workloads to skip their 5-minute exponential backoff
    Action items
    • Check the certificate of the TCP load balancer in front of Vault with the Blackbox exporter, as for the Layer-7 load balancers
    • Deploy the Reloader controller to roll Vault when its certificate data changes
    • Change theatre-envconsul so envconsul no longer manages the child process and only injects secrets at container startup
    Lessons

    A system that almost every service depends on, such as the secrets store, can take everything down at once, and failure scenarios like Vault becoming unreachable had not been tested enough. Assuming the certificate had expired, when it had been renewed but not reloaded, added a slow and unnecessary recreation step to the recovery.

  4. Symptoms

    At 10:43 on 14 August 2020 two of the six ingress controller pods in the cluster were in a crash loop. Restarting those pods did not fix them.

    Root cause
    Component
    Contributing factor
    Detection

    Two of the six ingress controller pods were seen crash-looping at 10:43; the incident was declared at 11:01.

    Remediation
    • restarted the leader ingress controller pod so the other replicas could connect and get the latest nginx configuration
  5. 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.

Check your cluster for this

These 5 cases involve Node pool and In-memory cache. 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 cause4

Capacity exhaustion2 cases

  1. 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
  2. IL-0093 Ingress controller pods crash-looped one after another because the leader pod had exhausted its shared memory

Breaking change in an upgrade1 case

Organisation
  1. IL-0101 After Google forced a GKE control plane upgrade to 1.33.2 at a deprecation deadline, no new node could initialise, so autoscaling and spot node replacement stopped for 15 hours

Certificate or credential expiry1 case

Organisation
  1. IL-0460 Vault served an expired TLS certificate and almost every GoCardless service pod crash-looped, a 22-minute full outage

Faulty deployment1 case

Organisation
  1. IL-0467 Boskos crash-looped after a node drain started it from a buggy StatefulSet image, failing Kubernetes PR jobs for 9 hours