Skip to content
Latchkey

PG::ConnectionBad could not connect to server in CI

ActiveRecord could not open a connection to Postgres. Either the service container was not up yet, the host/port is wrong, or credentials do not match. Connecting to a database service early in a job is a classic transient timing failure.

What this error means

Tests fail at connect time with PG::ConnectionBad (connection refused, no such host, or auth failed). Sometimes intermittent when the Postgres service is still starting.

rails
PG::ConnectionBad: could not connect to server: Connection refused
        Is the server running on host "localhost" (127.0.0.1) and accepting
        TCP/IP connections on port 5432?

Common causes

Service not ready yet

Tests connected before the Postgres service container finished booting and started accepting TCP connections.

Wrong host or port

database.yml/DATABASE_URL points at the wrong host (e.g. localhost vs the service network alias) or port.

Credential mismatch

The configured user/password/database does not match what the Postgres service was started with.

How to fix it

Wait for readiness and fix the address

Gate the test step on Postgres accepting connections, and point config at the right host.

Terminal
# wait until Postgres is ready
until pg_isready -h localhost -p 5432; do sleep 1; done
# or use a service health-check in the workflow before tests

Use DATABASE_URL matching the service

.github/workflows/ci.yml
env:
  DATABASE_URL: postgres://postgres:postgres@localhost:5432/myapp_test

How to prevent it

  • Add a readiness gate (pg_isready or a service health-check) before tests.
  • Drive connection settings from DATABASE_URL aligned with the service.
  • On self-healing managed runners (Latchkey), transient connection failures from a slow-starting database service are auto-retried so a momentary timing blip does not fail the job.

Related guides

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