Skip to content
Latchkey

Backstage "Failed to initialize database" (Postgres) in CI

The Backstage backend initializes its database on startup. In CI the Postgres service or its connection settings often are not ready, so the backend aborts with a connection or auth failure.

What this error means

The backend exits during startup with "Failed to connect to the database" and an underlying "ECONNREFUSED 127.0.0.1:5432" or "password authentication failed".

backstage
Backend failed to start up Error: Failed to connect to the database
    at ...
  cause: Error: connect ECONNREFUSED 127.0.0.1:5432

Common causes

No Postgres service or it is not ready yet

The job has no Postgres service container, or the backend starts before the database is accepting connections, giving ECONNREFUSED.

Missing or wrong connection config

The backend database block reads env vars that are unset in CI, so host, port, user, or password are empty.

How to fix it

Run a Postgres service and wait for it

  1. Add a Postgres service container to the job.
  2. Provide the connection env vars the config reads.
  3. Wait until Postgres is ready before starting the backend.
.github/workflows/ci.yml
services:
  postgres:
    image: postgres:16
    env: { POSTGRES_PASSWORD: postgres }
    ports: ['5432:5432']
    options: >-
      --health-cmd pg_isready --health-interval 10s --health-retries 5

Supply the database env the config expects

Set the host, port, user, and password vars referenced in app-config so the connection is built correctly.

.github/workflows/ci.yml
env:
  POSTGRES_HOST: localhost
  POSTGRES_PORT: '5432'
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: postgres

How to prevent it

  • Use a Postgres service container with a health check gate.
  • Provide all database connection env vars the config reads.
  • Fall back to the in-memory or better-sqlite3 store for pure CI checks that do not need Postgres.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →