dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/Error Library/postgresql-database-system-is-starting-up
PostgreSQL
PostgreSQL 14–18Recovery & Startup
8 min read
FATAL: the database system is starting up / in recovery mode (SQLSTATE 57P03)

PostgreSQL "the database system is starting up" — Should I Wait or Intervene?

Diagnosing 57P03: separating routine startup from looping crash recovery, decoding pg_isready exit codes (0, 1, 2), inspecting pg_controldata, and archive command stalls.

Reviewed by:Principal Database Reliability Architect
Tested Versions: PostgreSQL 18.6 & 17.11 (Alpine Linux / Docker 29.7) | Tarihsel: PostgreSQL 14, 15, 16

Operational Verification & Reliability Metadata

Last Technical Review: 30 Ekim 2026
Tested VersionsPostgreSQL 18.6 & 17.11 (Alpine / Docker 29.7) | Tarihsel: 14.10, 15.6, 16.4
Required PrivilegesOS access (to execute pg_isready, pg_controldata, and inspect postgresql.log)
Risk Assessment
HighKilling the postmaster with SIGKILL (-9) while redo recovery is in progress causes severe physical page corruption
Expected OutputDistinguishing normal startup from looping recovery using pg_isready exit codes (0, 1, 2) and redo starts/done log analysis
Rollback Procedure:Monitor WAL redo progression; if recovery loops, verify restore_command and disk space
PostgreSQL Docs: pg_isready & Server Startup
First 60 Seconds Emergency Protocol:

The error string is a symptom, not the root cause. Do not restart the server blindly. Run the diagnostic queries below to pinpoint the actual failure mode.

▸Symptom

plaintext
FATAL: the database system is starting up FATAL: the database system is in recovery mode FATAL: the database system is shutting down FATAL: the database system is not yet accepting connections FATAL: the database system is in an inconsistent state

All coalesce under PostgreSQL SQLSTATE code `57P03` (cannot_connect_now).

This error confronts database reliability engineers with an urgent decision: "Should I wait, or should I intervene immediately?"

The purpose of this guide is to resolve that decision using empirical telemetry rather than panic.


▸Three Core Scenarios

  1. 1Routine Boot Initialization: The daemon just started; shared memory is initializing, and preloaded extensions are binding. Connections will be accepted within seconds. Do not intervene; wait.
  2. 2Crash Recovery (WAL Redo): The server halted uncleanly (power failure, kernel OOM kill, power loss). PostgreSQL is replaying Write-Ahead Logs (REDO) from the last checkpoint to guarantee ACID consistency. Depending on dirty buffer volumes before the crash, this may take between 30 seconds and 20 minutes.
  3. 3Stuck / Looping Recovery: Recovery is stalled in a crash-loop or hanging indefinitely waiting for a missing archive segment. Immediate intervention is required.

▸Triage via `pg_isready` Exit Codes

PostgreSQL provides `pg_isready` specifically to evaluate server readiness:

bash
pg_isready -h localhost -p 5432 -d app echo $?

Exit code semantics:

  • •0: Cluster ready; accepting client connections.
  • •1: Cluster running, but rejecting client connections (starting up or running redo recovery) → Scope of this guide (57P03).
  • •2: No response (daemon is down or port is blocked) → Scope of guide H-07.
  • •3: Invalid invocation arguments.

An exit code of 1 proves PostgreSQL is active and repairing itself; killing the process here is catastrophic.


▸Is Recovery Progressing or Deadlocked?

Inspect the server logs for redo checkpoints:

plaintext
LOG: database system was not properly shut down; automatic recovery in progress LOG: redo starts at 0/1A2B3C48 LOG: redo done at 0/2F9D11A0 LOG: database system is ready to accept connections
  • •Progressing: LSN numbers advance sequentially between redo starts at and redo done at. Active disk I/O confirms healthy recovery.
  • •Crash Loop: The exact same redo starts at line logs repeatedly every few minutes. The postmaster completes redo and segfaults before opening connections (usually disk exhaustion or corrupt WAL headers).
  • •Archive Stall: The restore_command repeatedly fails to fetch a required segment.

Querying Cluster State via pg_controldata

When psql is locked out, read the on-disk control block directly:

bash
pg_controldata "$PGDATA" | grep -E 'cluster state|Latest checkpoint|REDO'

▸Emergency Intervention Best Practices

CAUTION
Never Execute `kill -9` During Redo Recovery! Transmitting SIGKILL to an active postmaster undergoing crash recovery will corrupt page headers in shared memory and leave the filesystem in an irrecoverable state.

Throttling Reconnection Surges

When PostgreSQL finally emits database system is ready to accept connections, hundreds of queued client connection pools will simultaneously flood port 5432. Throttle traffic at the PgBouncer pooler tier to allow shared buffers to warm up gracefully.


▸Related Error Guides & Hub Links

Other Database Error Triage Playbooks

Other battle-tested diagnostic guides for high-severity database errors.

All Errors (50)