Fix PostgreSQL `server closed the connection unexpectedly` Errors
A practical guide to diagnosing PostgreSQL server-closed-connection errors across restarts, timeouts, poolers, network drops, and application transaction handling.
PostgreSQL clients report server closed the connection unexpectedly when a connection that was previously open disappears before the client finished its work. That message is different from a refused connection or a bad password. The application reached PostgreSQL, began using a session, and then lost the backend process, socket, or pooler path underneath it.
The right fix starts with timing. If the error appears during a deploy, maintenance window, failover, or database restart, it is probably a lifecycle event that the application should retry safely. If it appears during one endpoint, one migration, or one background job, look for query cancellation, memory pressure, idle transaction cleanup, a pooler timeout, or a network boundary closing idle sockets.
What the error usually means
The phrase comes from client libraries when the server side of the connection goes away without a normal SQL error response. PostgreSQL itself may have shut down cleanly, a backend may have been terminated, a connection pooler may have closed an idle server connection, or a proxy may have dropped a long-lived TCP session. The same application-level symptom can therefore have very different causes.
Do not start by raising every timeout. First separate planned events from unplanned disconnects. PostgreSQL supports several shutdown modes, and during restarts existing clients can be disconnected while the server reopens for new sessions. Managed providers may also perform maintenance, failover, certificate rotation, or networking changes that briefly break existing sessions. Those events should be rare and recoverable, but application code still needs to treat database connections as replaceable.
| Signal | Likely cause | First check |
|---|---|---|
| Many services fail at the same timestamp | Restart, failover, maintenance, or network event | Check provider events, PostgreSQL logs, and app deploy history |
| One long query fails repeatedly | Timeout, backend termination, or resource pressure | Check query duration, statement timeout, logs, and memory/temporary-file pressure |
| Errors appear after idle periods | Pooler, proxy, firewall, or TCP idle timeout | Compare pooler settings, app keepalive behavior, and connection reuse |
| Only pooled endpoint fails | PgBouncer or managed pool behavior | Check pool mode, server lifetime, server idle timeout, and transaction boundaries |
| One worker fails after using a transaction | Application transaction scope or connection reuse bug | Roll back failed transactions and make the worker reconnect cleanly |
Check logs before changing settings
The fastest way to avoid guessing is to align three clocks: application logs, database logs, and deploy or provider events. If the database log shows a shutdown, crash recovery, administrator termination, or connection reset at the same time as the client error, the investigation is already narrowed. If the database log is quiet, the broken path may be between the client and PostgreSQL: a pooler, load balancer, proxy, NAT gateway, firewall, or container networking layer.
On self-hosted PostgreSQL, inspect the server log around the exact timestamp and check whether a system service restarted the database. On managed PostgreSQL, use the provider dashboard and event history first. A healthy managed setup should make maintenance and failover visible enough that a connection loss during that window is explainable rather than mysterious.
When only one SQL path fails, capture the statement class and transaction scope. A large export, migration, index build, or analytical report can run long enough to cross application request deadlines, proxy idle limits, or database timeouts. If the client cancels work or disappears while PostgreSQL is still processing, the next operation on that stale connection may surface as a closed-connection error.
Reconnect safely, then fix the cause
Applications should not reuse a connection after this error. Close it, remove it from the pool, open a fresh connection, and retry only if the operation is safe to retry. A read-only query is usually safe. A write transaction is safe only when the application has an idempotency key, a natural unique constraint, or a clear way to determine whether the previous attempt committed. PostgreSQL can abort a backend before the client receives the final result, so blindly repeating payment, email, or inventory writes can create product bugs.
Most mature PostgreSQL drivers and ORMs can evict broken connections from their pools, but they still need sensible configuration. Keep application pools bounded, set request deadlines that are shorter than user-facing timeouts, and make background jobs reconnect between retries. For pooled deployments, remember that a pooler manages two different relationships: the client-to-pool connection and the pool-to-PostgreSQL server connection. A setting that recycles server connections can be perfectly normal, but the application must not assume a stale session is still alive forever.
Fix common root causes
If the issue follows deploys or database maintenance, make startup and retry behavior boring. Run readiness checks before accepting traffic, let the application reconnect after a failed query, and keep migrations separate from request-serving traffic. A deployment that restarts every process at once can also create a reconnect storm, so PgBouncer or a managed pool helps absorb the spike after PostgreSQL is available again.
If the issue follows idle periods, review every layer that can close an unused socket. PostgreSQL has keepalive-related connection settings, operating systems have TCP keepalive defaults, PgBouncer can close idle server connections, and cloud load balancers often have idle connection limits. The fix is not always to make timeouts longer. Often the better fix is to let the application validate or refresh idle connections before handing them to request code.
If long queries trigger the error, diagnose the query instead of only raising timeouts. Check pg_stat_activity, statement timeout settings, lock waits, and the plan for the slow statement. A query that exceeds a request deadline may need an index, batching, a background job, or a reporting replica. Raising the deadline can be reasonable for maintenance work, but it should be paired with observability so slow SQL does not silently become normal.
A practical runbook
Start by recording the exact error, timestamp, database endpoint, and whether the connection went through PgBouncer or a direct PostgreSQL host. Compare that timestamp with provider events, database logs, and application deploys. If many clients failed together, treat it as a lifecycle or network event and verify that clients reconnected successfully. If one path failed, inspect the query, transaction length, pool settings, and any idle period before the failure.
Then fix recovery behavior. Broken connections should be discarded, failed transactions should be rolled back, and retries should be limited to operations that are idempotent or explicitly safe. For ArmorDB users, the PgBouncer docs are useful when disconnects appear around pooling behavior, while the connection refused guide helps distinguish this error from a listener or networking problem that happens before a session is created.
Takeaway
server closed the connection unexpectedly is a connection-lifecycle error, not a single PostgreSQL setting. Match the timestamp to logs and events, discard the broken connection, reconnect cleanly, and only retry writes when the application can prove the retry is safe. Once recovery is correct, the remaining work is usually specific: maintenance handling, pooler settings, idle socket behavior, or a slow query that should be fixed at the source.
Sources and further reading
Topic
Short-Form & Quick Fixes
Updated
Jul 28, 2026
Read time
6 min read
ArmorDB Engineering writes about PostgreSQL operations, security, and infrastructure decisions for teams building production apps on ArmorDB.
Read next
Deep Dives · 9 min read
PostgreSQL Logical Replication Slots: A Managed Database Deep Dive
A practical guide to PostgreSQL logical replication slots, WAL retention, monitoring, failure modes, and safer managed database operations.
Read articleTech-News & Trends · 7 min read
PostgreSQL 19 Beta 2: What Managed PostgreSQL Teams Should Test
PostgreSQL 19 Beta 2 is a useful checkpoint for testing authentication, migration, replication, and SQL compatibility before a future managed PostgreSQL upgrade.
Read article