Applies to: any deployment; both binaries.
Audience: on-call operators.
Risk: medium — the orchestrator SIGKILLed (or forced) the process before
its graceful shutdown budget finished. Durable, at-least-once traffic survives
and is redelivered; best-effort traffic in flight at the kill is lost.
On SIGTERM/SIGINT GoBridge drains in phases: settle in-flight work (bounded
by drain_timeout), release leases, close transports and stores, then stop
HTTP — the whole sequence bounded by shutdown_timeout
(deployment-guide.md).
The orchestrator must give the container more stop time than
shutdown_timeout, or it sends SIGKILL mid-drain. A second SIGINT/SIGTERM
also forces an immediate exit before drain completes.
Evidence the process was killed/forced before graceful drain finished:
exit 0: the orchestrator reports SIGKILL (exit 137 =
128+9) or exit code 2 (a second signal forcing immediate exit —
exit codes).shutdown_timeout
(a config bug, not an incident-time action).shared_outbox records: preserved.
Unsettled deliveries were never acked to the source, so the broker
redelivers on restart; persisted outbox records are recovered by the drainer.
Expect duplicates on routes without downstream dedup.Persist Ephemeral traffic: can be lost. Anything accepted
but not yet settled/persisted at the kill carries no delivery contract and is
gone — it is not redelivered.OutboxDepth should show the recovered backlog draining
after restart; a persistent non-draining depth is a separate incident
(outbox backlog / stuck drain).MQTTRouterStalePurged / MQTTRouterDropped
around the kill window quantify best-effort loss (QoS 0 only; QoS 1/2 counted
in MQTTRouterStalePurged is redelivered, not lost).MQTTAckAfterReconnect after restart — a burst predicts broker
redelivery duplicates; verify downstream idempotency on direct_hold routes.shutdown_timeout (ECS
stopTimeout, Kubernetes terminationGracePeriodSeconds, systemd
TimeoutStopSec), and keep drain_timeout shorter than shutdown_timeout
for headroom.