Skip to content
Latchkey

Ecto "mix ecto.migrate" Connection Refused in CI

Ecto could not connect to Postgres when running mix ecto.migrate. The Repo never reached the server - a readiness or configuration problem, not a migration SQL problem.

What this error means

mix ecto.migrate (or ecto.setup) fails with DBConnection.ConnectionError / "connection refused", often while the database service is still booting. It commonly clears on retry once Postgres accepts connections.

Elixir output
** (DBConnection.ConnectionError) connection not available and request was
dropped from queue after 2000ms ... connection refused - :econnrefused

Common causes

Postgres service not ready yet

In CI the database is often a service container still starting when ecto.migrate runs, so the connection is refused. This is transient.

Repo config points at the wrong host/port

The config/test.exs (or env-driven) Repo settings reference a host the runner cannot reach, so every connect fails the same way.

Transient network blip

A brief connectivity drop to a remote database causes an intermittent failure that succeeds on retry.

How to fix it

Wait for Postgres, then migrate

Block on readiness so the migrate task does not race the database boot.

Terminal
until pg_isready -h "$PGHOST" -p "$PGPORT"; do sleep 1; done
mix ecto.create && mix ecto.migrate

Add a service healthcheck

.github/workflows/ci.yml
services:
  postgres:
    image: postgres:16
    env: { POSTGRES_PASSWORD: postgres }
    options: >-
      --health-cmd pg_isready --health-interval 5s --health-retries 10

Verify the Repo configuration

  1. Confirm the Repo hostname/port/credentials match the reachable service (service name, not localhost, with containers).
  2. Check that the right config environment (MIX_ENV=test) is loaded.
  3. Retry once dependencies are healthy to confirm a transient failure.

How to prevent it

  • Gate ecto.migrate on pg_isready or a service healthcheck.
  • Keep Repo host/port/credentials aligned with the CI network.
  • Set MIX_ENV=test so the correct config is used.

Frequently asked questions

What causes ""connection refused" (Ecto)"?
In CI the database is often a service container still starting when ecto.migrate runs, so the connection is refused. This is transient.
How do I fix "connection refused" (Ecto)?
Block on readiness so the migrate task does not race the database boot.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card