# X_DB_DRAIN_TIMEOUT

## Means

the pool did not drain inside its shutdown budget

## Typical cause

`As of 2026-08-27`: `close()` gave up waiting for a role's pool to hand its connections back. `Bun.SQL`'s `end()` waits on an outstanding RESERVED connection and never stops — measured three runs per case on Bun 1.3.14 **and** 1.4.0, with the database perfectly healthy — so before `PoolProfile.drainTimeoutMs` a shutdown that met a pinned connection never finished, and the operator's only signal was a container that burned its whole termination grace period before SIGKILL. Raised on the elapsed time, because the driver RESOLVES when it gives up rather than rejecting: a drain that silently abandoned in-flight work looked exactly like a clean one. `migrate` and `replicator` are `0` and still wait forever, deliberately — a run-once role cutting off its own session mid-statement is worse than a slow exit

## Fix

find the statement that will not finish — `psql "$DATABASE_URL" -c "select pid, state, query from pg_stat_activity where state <> 'idle'"` — or raise `drainTimeoutMs` in `postgresClient({ profile })` for the role `cause` names

[Entity and database](/error-codes#entity-and-database)
