PostgreSQL Lock File Exists (SQLSTATE F0001)

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

  1. Unclean shutdown left a stale postmaster.pid — if the PostgreSQL server was killed with kill -9, terminated by the OOM killer, or lost power without a clean shutdown, the postmaster.pid file is never removed. On the next startup attempt PostgreSQL finds it and raises this error.

  2. Two instances pointing at the same data directory — running pg_ctl start twice, 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.

  3. Container restart without volume cleanup — in Docker or Kubernetes setups, a container crash may leave postmaster.pid in a persistent volume. When a new container starts and mounts the same volume, it finds the stale file.

  4. Data directory restored from snapshot or backup — restoring a data directory from a filesystem snapshot or backup often includes a postmaster.pid from the time the snapshot was taken. PostgreSQL will reject startup until the file is removed.

  5. 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.

  1. 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.pid
    

    The first line of postmaster.pid is the PID. Verify it is not a live PostgreSQL process:

    kill -0 <PID>   # exits 0 if process exists, non-zero if not
    
  2. If no PostgreSQL process is running, remove the stale lock file:

    rm /var/lib/postgresql/data/postmaster.pid
    

    Then start PostgreSQL normally:

    pg_ctl -D /var/lib/postgresql/data start
    # or
    systemctl start postgresql
    
  3. If 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 stop
    
  4. For Docker/Kubernetes, add an entrypoint step that removes postmaster.pid before starting the server, since containers can restart after unexpected termination:

    rm -f /var/lib/postgresql/data/postmaster.pid
    exec docker-entrypoint.sh postgres
    

    The official postgres Docker image already handles this automatically since PostgreSQL 10.

  5. After restoring from backup or snapshot, always delete postmaster.pid from the restored data directory before starting the server:

    rm -f /path/to/restored/pgdata/postmaster.pid
    

Additional Information

  • SQLSTATE class F0 contains only two conditions: F0000 (config file error, the generic parent) and F0001 (lock file exists). This class is distinct from other startup errors, which are typically in class 57 (operator intervention) or 58 (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>/cmdline to 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.pid the 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.pid exists 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.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.