PostgreSQL "terminating connection due to administrator command" — Who Dropped the Session?
Real root causes behind 57P01: pg_terminate_backend, server restarts, cloud failovers, and poolers. Matching adjacent log entries to SIGTERM events.
Operational Verification & Reliability Metadata
The error string is a symptom, not the root cause. Do not restart the server blindly. Run the diagnostic queries below to pinpoint the actual failure mode.
▸Symptom
FATAL: terminating connection due to administrator commandOn the client application side (Node.js pg, Go pgx, Python psycopg2, JDBC), this typically surfaces as:
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.SQLSTATE error code: 57P01 (admin_shutdown).
pg_terminate_backend(). PostgreSQL outputs this exact text whenever a backend worker process receives an operating system SIGTERM (signal 15). The identity of the signaling process is not included in the error string — therefore, troubleshooting must begin not with the message itself, but by inspecting adjacent lines in the PostgreSQL server log.▸1. Disambiguating the True Event
Four distinct log messages within the 57 class indicate completely different operational events. Confusing them leads to misguided investigations:
| Log String | What Actually Happened? | SQLSTATE |
|---|---|---|
terminating connection due to administrator command | Process received SIGTERM: pg_terminate_backend, pg_ctl stop/restart, systemd service manager, cloud failover | 57P01 |
terminating connection because of crash of another server process | Another backend crashed (e.g. Segfault); postmaster terminated all sibling backends to protect shared memory | 57P02 |
terminating connection due to idle-session timeout | idle_session_timeout threshold exceeded (PostgreSQL 14+) | 57P05 |
terminating connection due to idle-in-transaction timeout | Session remained idle within an open transaction beyond idle_in_transaction_session_timeout | 25P03 |
When 57P01 is logged, the cause is never a passive timeout: an external entity or process explicitly terminated the session. The diagnostic question is no longer "why did it disconnect?", but "who sent the SIGTERM?"
▸2. Step-by-Step Diagnostic Flow
Step 1: Locate the Closing Log Entry and Last Executed Query
When PostgreSQL receives a SIGTERM for a backend, it records diagnostic context:
LOG: server process (PID 48213) was terminated by signal 15: Terminated
DETAIL: Failed process was running: SELECT * FROM monthly_reports WHERE month = '2026-09'The DETAIL line is invaluable: it reveals the exact SQL statement active when the backend was severed. If it shows a long-running reporting query, an automated monitoring watchdog, pooler timeout, or cron reaper likely terminated it deliberately.
Step 2: Did All Sessions Drop Simultaneously or Selectively?
Inspect session ages on the running instance:
SELECT count(*) FILTER (WHERE state = 'active') AS active_count,
count(*) FILTER (WHERE state = 'idle') AS idle_count,
min(backend_start) AS oldest_session,
max(backend_start) AS newest_session
FROM pg_stat_activity
WHERE backend_type = 'client backend';- •If all sessions dropped simultaneously: The database instance restarted. Search the logs for
received fast shutdown requestordatabase system is shut down. - •If only isolated sessions dropped: The database engine remained online; SIGTERM was directed selectively at specific PIDs.
Step 3: Enable Disconnection Logging
PostgreSQL does not log invocations of pg_terminate_backend by default. To capture session lifespans and termination reasons for future incidents:
ALTER SYSTEM SET log_disconnections = on;
SELECT pg_reload_conf();Step 4: Triage the Top Three Root Causes
- 1Managed Cloud Database Engines (AWS RDS / Aurora / GCP Cloud SQL / Azure Database): Automated minor version patching, storage autoscaling restarts, or multi-AZ failovers generate this exact
57P01log. Always cross-reference the provider's Event Log. - 2Connection Poolers (PgBouncer / Odyssey): If PgBouncer's
server_idle_timeoutis shorter than the server-side idle threshold, stale server connections may be handed to clients, triggering immediate failures. - 3Application Identification: Always configure
application_namein connection strings:
postgresql://user:pass@host:5432/db?application_name=order_processing_service This ensures that audit queries on pg_stat_activity clearly attribute which subsystem is involved.
▸3. Resolution and Resilience Best Practices
1. Implement Strict Application-Level Retry Classification
57P01 indicates a connection drop. However, blind retries are dangerous:
57P01, 57P02, 08006 → Connection severed: Retry ONLY for IDEMPOTENT requests (e.g. SELECT) on a fresh connection.
57P03 → Server starting up: Apply exponential backoff and retry.
25P03, 57P05 → Policy timeout: Do NOT retry; optimize query and transaction duration.INSERT / UPDATE) fails with 57P01, the client cannot know whether the server executed COMMIT before dropping the socket. Without application-level idempotency tokens, automatic retries can duplicate financial records.2. Pool Health Checks & Retirement Alignment
Verify connection liveness before checking out from poolers (SELECT 1;). In application pool configurations (such as HikariCP), ensure maxLifetime is at least 30 seconds shorter than firewall and PostgreSQL idle timeout thresholds.
▸Related Error Guides & Hub Links
- •PostgreSQL Connection Refused (H-07) — Port binding and firewall diagnosis
- •PostgreSQL Conflict with Recovery (H-11) — Standby replication query cancellation
- •PostgreSQL Too Many Clients Already (H-01) — Exhausting backend connection slots
- •PostgreSQL Hub — Architecture, runbooks, and engine overviews
Other Database Error Triage Playbooks
Other battle-tested diagnostic guides for high-severity database errors.
PostgreSQL Connection Exhaustion & too many clients Triage
Root causes of FATAL: sorry, too many clients already and remaining connection slots errors, read-only pg_stat_activity diagnosis with privilege boundaries, and two-tier pooling mitigation.
PostgreSQL password authentication failed: Root Cause and Fix
Four root causes of psql password authentication failed: incorrect password, md5/SCRAM mismatch, pg_hba.conf rule ordering, and port/cluster confusion. Step-by-step triage.
PostgreSQL connection refused: 8-Step Definitive Triage
Difference between connection refused, timeout, and no pg_hba entry; triage for listen_addresses, port conflicts, firewalls, and Docker container mappings.