Rails "PG::ConnectionBad" During Migrations in CI
ActiveRecord could not establish a connection to Postgres when running db:migrate. The adapter never reached the server - a connectivity or configuration issue, not a migration SQL problem.
What this error means
rails db:migrate (or db:prepare) fails with PG::ConnectionBad / ConnectionNotEstablished, often "could not connect to server" or "Connection refused". It frequently clears on retry once the database service is up.
ActiveRecord::ConnectionNotEstablished: connection to server at "127.0.0.1",
port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
(PG::ConnectionBad)Common causes
Database service not ready
A Postgres service container is still starting when db:migrate runs, so the connection is refused. This is the most common CI cause and is transient.
Wrong host/port or DATABASE_URL
The database.yml or DATABASE_URL points at a host the runner cannot reach (e.g. localhost vs the service name), so every connection fails.
Transient network blip
A brief connectivity drop between the runner and a remote database can cause an intermittent connection failure that succeeds on retry.
How to fix it
Wait for Postgres before migrating
Block on readiness so the migrate step does not race the database boot.
until pg_isready -h "$PGHOST" -p "$PGPORT"; do sleep 1; done
bin/rails db:prepareAdd a service healthcheck
services:
postgres:
image: postgres:16
env: { POSTGRES_PASSWORD: postgres }
options: >-
--health-cmd pg_isready --health-interval 5s --health-retries 10Verify the connection settings
- Confirm
DATABASE_URL/database.ymlhost matches the CI network (service name, notlocalhost, when using containers). - Check the port is exposed and credentials match the service env.
- Retry once dependencies are healthy to confirm a transient failure.
How to prevent it
- Gate
db:migrateonpg_isreadyor a service healthcheck. - Keep
DATABASE_URLaligned with the CI network topology. - Use
db:prepareso a fresh CI database is created and migrated consistently.