PostgreSQL raises SQLSTATE F0001 (lock_file_exists) when the server process finds an existing postmaster.pid file in the data directory during startup. The full message in logs typically reads:
FATAL: lock file "postmaster.pid" already exists
HINT: Is another postmaster (PID NNNN) running in data directory "/var/lib/postgresql/data"?
This error belongs to SQLSTATE class F0 (configuration file error) and is a fatal startup-time condition — the PostgreSQL server process exits immediately without accepting connections.
What This Error Means
The postmaster.pid file is a lock file that PostgreSQL writes to its data directory ($PGDATA) at startup. It records the PID of the running postmaster process along with the port, socket directory, and a few other runtime details. Its purpose is to prevent two PostgreSQL instances from accidentally sharing the same data directory, which would corrupt data.
When PostgreSQL starts, one of the first things it does is attempt to create postmaster.pid. If the file already exists, PostgreSQL reads the PID stored inside it and checks whether that process is still alive on the system. If a live process with that PID exists, PostgreSQL concludes another instance is already running on the same data directory and refuses to start. If the process is not running, PostgreSQL should normally detect this and start anyway — but under certain conditions (particularly after an unclean shutdown), it may still report lock_file_exists before determining liveness.
In practice this error almost always indicates either a genuine collision (two Postgres instances targeting the same $PGDATA) or a stale lock file left behind after a crash, power loss, or forced kill of the server process. Because this is a fatal pre-connection error, it surfaces only in server logs or on the terminal where you ran pg_ctl start — it is never seen as a SQL error by a client application.
Common Causes
Unclean shutdown left a stale
postmaster.pid— if the PostgreSQL server was killed withkill -9, terminated by the OOM killer, or lost power without a clean shutdown, thepostmaster.pidfile is never removed. On the next startup attempt PostgreSQL finds it and raises this error.Two instances pointing at the same data directory — running
pg_ctl starttwice, or having both a system service (systemd/init.d) and a manual invocation attempt to start on the same$PGDATA, causes the second attempt to see the lock file left by the first.Container restart without volume cleanup — in Docker or Kubernetes setups, a container crash may leave
postmaster.pidin a persistent volume. When a new container starts and mounts the same volume, it finds the stale file.Data directory restored from snapshot or backup — restoring a data directory from a filesystem snapshot or backup often includes a
postmaster.pidfrom the time the snapshot was taken. PostgreSQL will reject startup until the file is removed.Permissions or filesystem issue — in rare cases, PostgreSQL cannot remove the file at shutdown (e.g., filesystem mounted read-only), or the file was created by a different OS user and the current process cannot overwrite it.
How to Fix lock_file_exists
Before removing the lock file, confirm no PostgreSQL process is actually running on this data directory. Deleting a live lock file can lead to data corruption.
Check whether PostgreSQL is already running:
# Check for running postgres processes pg_lsclusters # Debian/Ubuntu with pg_ctlcluster # or ps aux | grep postgres # or check the PID recorded in the file cat /var/lib/postgresql/data/postmaster.pidThe first line of
postmaster.pidis the PID. Verify it is not a live PostgreSQL process:kill -0 <PID> # exits 0 if process exists, non-zero if notIf no PostgreSQL process is running, remove the stale lock file:
rm /var/lib/postgresql/data/postmaster.pidThen start PostgreSQL normally:
pg_ctl -D /var/lib/postgresql/data start # or systemctl start postgresqlIf another PostgreSQL instance is already running on the same data directory, you must either stop the existing instance or point the new instance at a different
$PGDATA:pg_ctl -D /var/lib/postgresql/data stopFor Docker/Kubernetes, add an entrypoint step that removes
postmaster.pidbefore starting the server, since containers can restart after unexpected termination:rm -f /var/lib/postgresql/data/postmaster.pid exec docker-entrypoint.sh postgresThe official
postgresDocker image already handles this automatically since PostgreSQL 10.After restoring from backup or snapshot, always delete
postmaster.pidfrom the restored data directory before starting the server:rm -f /path/to/restored/pgdata/postmaster.pid
Additional Information
- SQLSTATE class
F0contains only two conditions:F0000(config file error, the generic parent) andF0001(lock file exists). This class is distinct from other startup errors, which are typically in class57(operator intervention) or58(system error). - PostgreSQL has handled stale lock file detection (checking if the recorded PID is still alive) since at least PostgreSQL 8.0. For modern versions (9.6+), on Linux, PostgreSQL additionally checks
/proc/<PID>/cmdlineto confirm the process is actually a PostgreSQL postmaster, reducing false positives. - This error is never seen by client drivers or ORMs — it occurs before any network socket is open. Applications will see a connection-refused error (
ECONNREFUSED) rather than this SQLSTATE. - On Windows, PostgreSQL uses
postmaster.pidthe same way but also holds a lock on the file using Windows file locking APIs, so stale files from crashes should be detected more reliably. - Related operational concern: if
postmaster.pidexists but the PID it references belongs to a non-PostgreSQL process (PID reuse after a crash), PostgreSQL may still raise this error. Removing the file is the correct resolution in that case.
Frequently Asked Questions
Is it safe to just delete postmaster.pid?
Only if you have confirmed that no PostgreSQL instance is actively running against that data directory. Check the PID in the file with kill -0 <PID> or ps aux | grep <PID>. If the process does not exist, it is safe to delete the file. If you delete a live lock file, you risk running two PostgreSQL instances on the same data directory, which causes corruption.
Why did this happen after my server crashed?
A clean PostgreSQL shutdown removes postmaster.pid as part of the shutdown sequence. A crash — from a kill signal, OOM kill, power loss, or host failure — skips the shutdown sequence, leaving the file behind. This is expected behavior and removing the stale file is the correct fix.
Can I prevent this from happening in production?
Use a process supervisor (systemd, Docker's restart policy) that calls pg_ctl stop or sends SIGTERM before restarting, giving PostgreSQL a chance to clean up. For containerized deployments, add an rm -f postmaster.pid guard in your entrypoint script. Regular monitoring for unexpected PostgreSQL process deaths will also help catch the underlying cause.
Does this error mean my database is corrupted?
Not by itself. The lock_file_exists error is purely about startup and the lock file — it says nothing about the state of your data files. However, if the previous shutdown was a crash, there may be a crash recovery step during the next successful startup (PostgreSQL will replay the WAL), which is normal and expected. Check the logs after successful startup for any recovery messages.