Incident Library
Applied filters Root causeSoftware defectSymptomIntermittent timeoutsFactorUnverified assumptionClear 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

Cases2 cases

1 to 2 of 2

  1. Symptoms

    During the first production canary of Decagon's move from GCP's managed connection pooler to self-managed PgBouncer, a small number of voice requests stalled mid-conversation and timed out after exactly 300 seconds. Other requests failed much earlier because the SQLAlchemy connection pool was exhausted.

    Trigger

    The move from GCP's managed connection pooler to self-managed PgBouncer enabled a different TLS path between PgBouncer and Postgres, which supplied the last of three conditions needed to expose the bug.

    Root cause
    Component
    Contributing factor
    Detection

    Sentry errors ("SSL connection has been closed unexpectedly") and SQLAlchemy connection-pool timeouts during the production canary, followed by a comparison of application spans with Postgres query timings.

    Remediation
    • Shortened the application name parameter so the ParameterStatus packet stayed below PgBouncer's small-packet parsing threshold
    Action items
    • Fix PgBouncer upstream so it checks SSL_pending() before going back to wait on epoll()
    Lessons

    Decagon's lesson is that an infrastructure migration does not only change one's own systems but can also expose latent bugs elsewhere in the stack: the move to self-managed PgBouncer supplied the last condition for a long-standing edge case involving SQLAlchemy, PgBouncer, OpenSSL and the PostgreSQL wire protocol.

  2. Symptoms

    On 10 July 2019 the Stripe API failed a substantial majority of requests twice, from 16:35 to 17:02 UTC and from 21:14 to 22:47 UTC. In the first period automated monitoring detected within a minute that a database cluster had failed to elect a new primary.

    Trigger

    The primary node of a database cluster failed at 16:35 UTC while one shard had several stalled nodes. The second period was set off by rolling the election protocol back to the previous minor version at 20:42 UTC.

    Root cause
    Component
    Contributing factor
    Detection

    Automated monitoring detected the failed election within a minute, and the team was alerted at 16:36 UTC. The second period was announced at 21:14 UTC by automated alerts that some shards in the cluster were unavailable.

    Remediation
    • Restarted all nodes of the database cluster, which forced a successful primary election
    • Updated the production configuration and restarted the database cluster's nodes
    • Ramped traffic back up, putting services for user-initiated API requests first
    Action items
    • Alert when nodes stop reporting their replication lag
    • Alert when a shard enters a state that could trigger the election fault
    • Work with the database maintainers on a fix for the underlying fault
    • Add circuit breaking on failed operations to particular database clusters
    • Use fault isolation to contain the impact of a single failed shard
    • Limit the resources used by clients that keep retrying failed requests
    • Add procedures and tooling that make rapid configuration changes during incident response safer
Check your cluster for this

These 2 cases involve Database and Database proxy and connection pooler. 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