F0001 — lock_file_exists
F0001
At a glance
F0001 is a startup ownership failure. PostgreSQL checks both the lock file and the shared-memory identity for the intended data directory; a live owner is different from a stale artifact left by a crashed postmaster.
| Field | Value |
|---|---|
| SQLSTATE | F0001 |
| Condition | lock_file_exists |
| Status | active |
| Known present by | 7.4 |
| Locked snapshots | 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3 |
| Macros | ERRCODE_LOCK_FILE_EXISTS |
| Aliases | — |
Meaning
CreateLockFile creates the lock file atomically with O_EXCL. If an existing file contains a PID, it uses kill(pid, 0) to distinguish a live process from a vanished one. For the data-directory lock it also reads the recorded shared-memory identifiers and calls PGSharedMemoryIsInUse; that helper only treats a segment associated with the intended DataDir as relevant, because accidental shared-memory ID matches are possible. An empty lock file is a separate F0001 branch and can mean that another server is still starting or that a previous startup crashed.
The SysV shared-memory startup path has the same boundary: an attached or indeterminate pre-existing segment is reported as still in use, while an unattached segment associated with the data directory can be removed and recreated. These guards prevent two postmasters from claiming one cluster.
Messages
- FATAL, SQLSTATE
F0001:lock file "%s" already exists.- Data-directory hint:
Is another postgres (PID %d) running in data directory "%s"?(the postmaster wording is selected for the encoded owner). - Socket-lock variants name
using socket file "%s"instead.
- Data-directory hint:
- FATAL, SQLSTATE
F0001:lock file "%s" is empty.- Hint:
Either another server is starting, or the lock file is the remnant of a previous server startup crash.
- Hint:
- FATAL, SQLSTATE
F0001:pre-existing shared memory block (key %lu, ID %lu) is still in use.- Hint:
Terminate any old server processes associated with data directory "%s".
- Hint:
Other lock-file I/O failures use errcode_for_file_access() and can receive a different SQLSTATE; do not collapse them into F0001.
Diagnosis
Confirm the exact PGDATA, socket directory, PID, start time, recorded device/inode identity, process owner, and postmaster log. A successful kill(pid, 0), or a failure whose errno is neither ESRCH nor EPERM, keeps the live-process branch active. ESRCH means that the PID does not exist; EPERM means that a process exists but the caller lacks permission to signal it. This guard treats EPERM as a candidate for the next identity checks because checkDataDir() and the 0600/0640 lock-file modes rule out a different-UID process as the competing postmaster; it does not by itself authorize deleting the lock. If the PID is gone or treated as a different-UID candidate, inspect the data-directory shared-memory IDs and whether an orphan backend still attaches before considering cleanup. An empty file is explicitly ambiguous, not proof of staleness.
Response
This is a startup FATAL, so there is no client transaction state to recover; after the ownership problem is resolved, start the server and use a new connection. If another postmaster or backend is live, stop or coordinate it through normal administration. Only after verifying the exact cluster, process identity, and shared-memory state may an operator follow the documented stale-lock cleanup path. Never remove a lock or shared-memory object by pathname, PID text, or numeric ID alone; if the owner is live, deletion risks split-brain (two postmasters claiming one cluster) and data loss.
Versions
The locked catalogue records this condition from 7.4; fixed startup and shared-memory paths are from PostgreSQL 18.6. No process, lock-file, or shared-memory fault was induced for this source-only entry.
Related
Sources
src/backend/utils/init/miscinit.c#L1262-L1427
src/backend/port/sysv_shmem.c#L306-L335
src/backend/port/sysv_shmem.c#L765-L835
The structured evidence record records live/stale guards, fixed FATAL messages, and the source/runtime boundary.