Cases2 cases
1 to 2 of 2
IL-0179With DEBUG logging and synchronous log output, a high-traffic service filled the 64 KB stdout pipe, so request threads blocked in write() while holding database connections and HikariCP ran dry, failing requests in 30-second burstsMUSINSA2026- Symptoms
The on-call engineer for a high-traffic service was alerted that requests were failing in large batches every 30 seconds.
- Trigger
DEBUG level logging was on in production when traffic surged, raising log volume to about 100 times normal while the service logged synchronously.
- Root cause
- Component
- Contributing factor
- Detection
The on-call engineer was alerted that requests were failing in large batches every 30 seconds.
- Action items
- Replace synchronous logging with TraceAwareAsyncAppender, which captures trace_id and span_id on the calling thread and drops logs instead of blocking when the queue is full (neverBlock=true)
- Keep the amount of log output at a sustainable level, since an asynchronous queue still fills under sustained overload
- Lessons
Removing AsyncAppender to keep trace IDs also removed the protection that kept request threads away from stdout back-pressure. A company-wide standard applies the same side effect to dozens of services, so check what a standard rests on and what working behaviour it takes away. ThreadLocal context does not cross into an asynchronous worker, but capturing it on the calling thread before handing the event off keeps both the IDs and the asynchronous output. Under extreme load, dropping log lines is preferable to stopping request handling.
IL-0035Worker nodes went NotReady after a new ElastAlert rule without memory limits used up node memoryNU.nl2019- 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.
These 2 cases involve Container runtime and Application database. 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
Configuration change2 cases
- Component
- Contributing factor
IL-0179With DEBUG logging and synchronous log output, a high-traffic service filled the 64 KB stdout pipe, so request threads blocked in write() while holding database connections and HikariCP ran dry, failing requests in 30-second burstsMUSINSA2026IL-0035Worker nodes went NotReady after a new ElastAlert rule without memory limits used up node memoryNU.nl2019