GitHub Actions Service Container Unhealthy - Postgres/Redis Not Ready
A job that uses a service container fails because the database or cache never reports healthy, or steps connect before it is ready - typically a missing health check or a port mismatch.
What this error means
The job fails during "Initialize containers", or a step gets "connection refused" connecting to the service, because the container was not ready when the step ran.
Error: Failed to initialize container postgres:16: health check never passed
# or
psql: error: connection to server at "localhost", port 5432 failed: Connection refusedCommon causes
No or failing health check
Without a health check, GitHub cannot tell when the service is ready, so steps may run before the database accepts connections.
Port or host mismatch
Steps must connect to the mapped port on localhost (for container-on-host jobs) or the service name (for container jobs). Using the wrong host/port refuses the connection.
How to fix it
Add a health check and map the port
Define a health check so the job waits for readiness, and connect to the mapped port.
services:
postgres:
image: postgres:16
env: { POSTGRES_PASSWORD: pw }
ports: ['5432:5432']
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s --health-timeout 5s --health-retries 5Connect to the right host and wait
- From a job running on the host, connect to localhost on the mapped port.
- From a container job, connect to the service by its label name (e.g. host postgres).
- Add a short wait/retry loop in the step if the client needs the DB fully initialized.
How to prevent it
- Always define a health check for service containers.
- Map and connect to the correct port/host for your job type.
- Retry the first connection so initialization races do not fail the job.