gobridge

Runbook: Lease Flapping / Split-Brain Suspicion

Applies to: clustered deployments with a distributed lease store (DynamoDB or equivalent). Audience: on-call operators. Risk: low to act — fencing tokens already reject stale writes; the work is diagnosing why leadership churns.

Symptom

Diagnosis

  1. Check each instance’s role. /api/v1/monitor/topology (authenticated) reports running state and the compact route list; /api/v1/monitor/ready returns the failover roleactive, standby, or standalone (http-api-monitor.md). Exactly one active owner per exclusive session is correct; two is the split-brain you are looking for.

  2. Read the lease metrics (monitoring.md#key-metrics): LeaseExpiries (leases lost without renewal — step-down), LeaseTransfers (re-acquired by this instance — hand-off), LeaseAcquireFailures, and the LeaseAcquireLatency / LeaseRenewLatency timers. High renew latency with rising expiries points at a slow or unreachable lease store.

  3. Confirm fencing is holding the line. STALE_FENCING_TOKEN means a guarded write (outbox claim/complete, lease renewal, route forward) was rejected because the caller’s fencing token version was older than the current owner’s — the safety mechanism working, not data corruption (troubleshooting.md#stale_fencing_token). NO_ROUTE_OWNER is the forwarder mid-hand-off and self-heals (troubleshooting.md#no_route_owner).

  4. Rule out a shared transport identity. MQTTSessionTakeover means two instances connected with the same client_id and are kicking each other — a different failure that looks like flapping (troubleshooting.md#adapter–runtime-diagnostic-metrics).

Action

Standalone multi-replica split brain (no distributed lease store)

The diagnosis above assumes a distributed lease store (DynamoDB). A different, more dangerous split brain occurs when an exclusive route runs with an in-memory / non-distributed lease store and the deployment is scaled to more than one replica: each process holds its OWN private lease, so every replica believes it is the sole active owner. There is no fencing between them — they all consume the same logical traffic in parallel (N-fold duplication) with no LeaseTransfers and no STALE_FENCING_TOKEN to signal it, because nothing is shared.

Detection. /api/v1/monitor/ready reports role: standalone (not active/ standby) on every replica, and duplicate downstream deliveries scale with the replica count. The builder emits a SPLIT-BRAIN RISK warning at startup when an exclusive/lease-bearing route is configured without a distributed lease backend — grep startup logs for it.

Action.