Download

server closed the connection unexpectedly

The connection to the server ended without a goodbye. Either the server process serving you died (often killed for using too much memory), the server restarted, or something on the network dropped an idle connection. The server log tells you which; reconnect, then fix that cause.

PostgreSQL error· Tested on PostgreSQL 18.6, psql 18.6· Updated 11 October 2026

server closed the connection unexpectedly

What it means

This is libpq, the client library, talking: it was reading from the server and the connection ended. There’s no SQLSTATE, because the server didn’t send an error, or didn’t get the chance:

server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.

Over TLS the same event is worded differently. A client built with OpenSSL 3 says SSL error: unexpected eof while reading; one built with an older OpenSSL says SSL SYSCALL error: EOF detected, because OpenSSL 3 changed how it reports a connection that ends without a TLS goodbye. When the server sent a message before closing, the TLS wording is SSL connection has been closed unexpectedly.

What matters is what came before it. If the server said why, its message is printed first: FATAL: terminating connection due to administrator command (its page), an idle-in-transaction timeout, or this one, sent to every other session when one server process crashes:

WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.

If nothing came before it, the server process vanished or the network dropped the connection. Either way, the transaction you were in is gone (rolled back), and you need a new connection.

Common causes

  1. The server process was killed, most often by the Linux out-of-memory killer, or a container memory limit, during a big query. When one server process dies like that, PostgreSQL restarts all of them, so every session is dropped.
  2. The server restarted or crashed: a crash, a restart for maintenance or a failover, a container that was stopped or redeployed.
  3. An idle connection dropped by something in between: a NAT gateway, firewall, load balancer or VPN that forgets connections idle for a few minutes. The next query finds it dead.
  4. A pooler or proxy (PgBouncer, a cloud proxy) closing server-side or client-side connections it considers too old or idle.

How to fix it

Read the server log first

It tells the causes apart. A killed process looks like this:

LOG:  client backend (PID 100) was terminated by signal 9: Killed
LOG:  terminating any other active server processes
LOG:  all server processes terminated; reinitializing

followed by database system was not properly shut down; automatic recovery in progress. If the log shows nothing at that time, the server didn’t drop you; something on the network did.

If processes are killed for memory

Signal 9 on Linux is usually the out-of-memory killer (dmesg or the container runtime’s events confirm it). Look at what was running: a query with a huge sort or hash, many parallel workers, or a large work_mem multiplied by many connections. Lower work_mem for that work, fix the query, reduce max_connections or use a pooler, or give the server more memory. The PostgreSQL documentation describes setting vm.overcommit_memory = 2 on Linux, so that the kernel refuses an allocation (which PostgreSQL reports as an out of memory error) instead of killing a process.

If idle connections are dropped

Turn on TCP keepalives so the connection never looks idle to the network, from the client:

postgresql://<user>@<host>/<database>?keepalives=1&keepalives_idle=60&keepalives_interval=10&keepalives_count=5

or on the server, with tcp_keepalives_idle and friends. Also set your connection pool’s idle timeout and maximum lifetime below the network’s timeout, and have it test connections before use.

Always be ready to reconnect

Restarts and failovers happen. Applications should catch a lost connection, open a new one, and retry the whole transaction, not only the last statement. One exception: if the connection dropped while COMMIT was in flight, you can’t tell whether it committed, so check before you run it again.

Reproduce it

In a throwaway PostgreSQL 18.6 container with TLS on, two sessions ran SELECT pg_sleep(10): one over TLS, one without (sslmode=disable). We killed the first one’s server process with kill -9. The TLS session got:

SSL error: unexpected eof while reading
connection to server was lost

The other session, untouched, was dropped too, because PostgreSQL restarts every process after one crashes:

WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.
connection to server was lost

The server log showed the three lines above, then automatic recovery, and database system is ready to accept connections about 0.3 seconds later. Our psql 18.6 is built with OpenSSL 3, so it printed the unexpected eof wording; we didn’t have a client built with an older OpenSSL to show SSL SYSCALL error: EOF detected.

In Inlet

When Inlet’s connection is lost, it shows the error, and What this error means opens this page. Inlet’s Activity monitor lists the server’s sessions, so after a restart you can see which applications have reconnected.

Inlet: a database client for the Mac

One native app for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and Redis. It explains errors where they happen, holds your edits until you save them, and keeps production read-only until you say so.

Version 0.1.0 · macOS 26 Tahoe or later · Apple silicon and Intel