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

Cases4 cases

1 to 4 of 4

  1. Symptoms

    On 4 March 2026 customers of the IONOS Container Registry got 504 Gateway Timeout errors when pushing or pulling container images, and deployments that relied on the registry were blocked. The status page first reported an increased error count on the registry at 09:23 UTC, saying customers might be unable to pull images.

    Trigger

    A migration combined with a temporary capacity constraint placed two critical control plane components on the same proxy instance, despite anti-affinity rules; the shared proxy then reached its concurrent connection limit.

    Root cause
    Component
    Contributing factor
    Remediation
    • Rolled back a component of the Kubernetes control plane to an earlier version
    • Provisioned additional proxy capacity
    • Moved the affected control plane components onto separate proxy instances
    Action items
    • Redesign registry-to-API connectivity so each node uses its own local proxy
    • Adjust alert thresholds to warn before proxy connection use approaches capacity
    • Deploy more infrastructure clusters and redistribute registries so no cluster exceeds safe capacity, with automation that keeps balancing load
  2. Symptoms

    At around 5.44pm UTC on 25 January 2022, Gitpod saw a high error rate when pulling images from Google Container Registry (gcr.io), with the error "cannot get manifest". About 10 minutes later users reported that they could not start workspaces.

    Root cause
    Component
    Contributing factor
    Detection

    The team noticed a high error rate on image pulls from GCR at around 5.44pm UTC; about 10 minutes later users reported that workspaces would not start, and the on-call team started incident response.

    Remediation
    • Created new workspace clusters in the EU and the US with a werft job
    • Redirected traffic to the new clusters
    Action items
    • Keep workspace data on cloud provider persistent volumes that survive node and cluster failures
    • Let users download their files from a workspace that cannot be started
    • Improve the workspace backup process
    • Use three DNS servers instead of one: a GCP-internal one, 8.8.8.8 and Cloudflare's 1.1.1.1
    • Do more DNS resiliency work, tracked in an epic
    • Improve support for multi-region clusters and later go multi-cloud
  3. Symptoms

    At 08:18 UTC on 13 July 2020, production Kubernetes pods began to be marked unavailable. The loss of pods spread through the clusters and reduced capacity until GitHub.com services went down.

    Trigger

    A container in the production pods exceeded its memory limit and was terminated; a routine DNS maintenance operation completed earlier had left the clusters unable to reach the image registry.

    Root cause
    Component
    Contributing factor
    Remediation
    • restarted the process with the cached DNS records so the clusters could reach the registry
    • fetched the container images, redeployed and recovered the services
    Action items
    • Improve monitoring so pod restarts cannot fail again in the same pattern
    • Minimise the dependency on the image registry
    • Expand validation during DNS changes
    • Re-evaluate all existing Kubernetes deployment policies
    • Improve progressive deployments so the impact of a deployment can be evaluated incrementally
    Lessons

    A container that production traffic does not need can still take pods out of service, because a pod is available only when all of its containers are healthy. ImagePullPolicy Always turns every container restart into a registry dependency, so an unrelated DNS change that breaks registry access turns a one-minute self-healing event into a long outage, and a mass redeploy spreads it.

  4. Symptoms

    Users reported that their jobs were not starting, with some sign that image pulls were involved. Many pods across the cluster were in error states related to image pulls, while applications that were already running were not affected.

    Trigger

    A change to the permissions on a storage bucket that one application needed to read. The application could no longer start, and its DaemonSet, running on roughly a thousand nodes of the cluster, went into a crash loop with imagePullPolicy: Always, so every restart pulled the image again although it was already on the node.

    Root cause
    Component
    Contributing factor
    Detection

    Users reported that their jobs were not starting; monitoring had not caught it first.

    Remediation
    • replaced the affected NAT instances so registry traffic came from new source IPs
    • reconfigured the static IPs and firewall rules so applications could reach the Cloud SQL database again
    Action items
    • Add an admission webhook that rejects floating image tags, starting with latest
    • Apply the image tag webhook to workload objects only, not to pods, after it blocked pods created by in-cluster controllers
    Lessons

    The speakers' takeaway is to be very careful with DaemonSets in large clusters: they say they had broken everything DaemonSets depend on, including DNS, Vault and the image repository, and that it is very easy to break things when managing them by the thousand. imagePullPolicy: Always made every crash-loop restart pull the image again. Sending all registry traffic through three NAT instances put the whole region behind three source IPs, which the registry rate-limited, and changing those IPs cut the connections to a critical database reached over the internet through them. An admission webhook on pods rejects the pods that controllers in the cluster create, where no user sees the error.

Check your cluster for this

These 4 cases involve Container registry and its credentials and Admission webhook. 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 cause2