Troubleshooting
Data Directory Troubleshooting
Verify PID liveness and
PG_VERSIONbefore changing persistent cluster state; never delete a lock or directory merely to bypass an error.
Postgres data directory ... is already in use
postmaster.pid names a process that is still alive. local-postgres rejects
with PostgresDataDirInUseError before spawning another server and does not
attach to, signal, or take ownership of it:
import { PostgresDataDirInUseError, startPostgres } from 'local-postgres'
try {
await startPostgres({ dataDir: '.postgres', postgresOutput: 'on-error' })
} catch (error) {
if (error instanceof PostgresDataDirInUseError) {
console.error(`Cluster ${error.dataDir} is already running as PID ${error.pid}`)
}
throw error
}
Verify the process before deciding whether its owner should stop it:
ps -p "$(head -n 1 .postgres/postmaster.pid)" -o pid=,command=
Use the original owner or an intentional
stopPostgresDataDir call to
stop a server you own. Do not start a second server against the same directory.
Stale postmaster.pid
When the PID no longer exists, local-postgres lets PostgreSQL perform its
normal stale-lock handling. On macOS, it also attempts exact-match recovery of
an unattached System V shared-memory segment recorded by that postmaster. See
Shared Memory Troubleshooting for the verification rules,
lifecycle coverage, and cases the package deliberately cannot recover.
If startup still fails, use postgresOutput: 'on-error' and follow
PostgreSQL's diagnostic instead of deleting the file or IPC resources blindly.
An invalid PID file produces Invalid postmaster.pid file. Inspect the file
and determine which interrupted tool owned the cluster before repairing
disposable state or restoring persistent state from its intended source.
Data Directory Version Mismatch
The resolved binary major version differs from the cluster's PG_VERSION.
Verify both values:
cat .postgres/PG_VERSION
postgres --version
Fix one of these:
- use a Postgres binary from the same major version as
PG_VERSION - choose a separate
dataDirfor the requested version - remove and recreate the directory only when its data is disposable
await startPostgres({
dataDir: '.postgres-18',
postgres: {
version: '18',
strategy: 'prefer-local',
},
})
See Data Directories for persistence and configuration ownership.