CI "wait-for-it.sh: timeout occurred" - Service Never Became Ready
A readiness wait (wait-for-it, dockerize, a poll loop) gave up before the dependent service began accepting connections. The service was still starting - a transient timing issue that usually clears when the wait has enough headroom or on a retry.
What this error means
A step fails with wait-for-it.sh: timeout occurred after waiting N seconds for host:port (or an equivalent "service did not become ready" message). A database, cache, or app container had not finished booting within the wait window. Re-running, or lengthening the wait, succeeds.
wait-for-it.sh: waiting 15 seconds for postgres:5432
wait-for-it.sh: timeout occurred after waiting 15 seconds for postgres:5432Common causes
The service was still starting when the wait expired
A database or app container can take longer than a short wait window on a busy runner. The port is not listening yet, so the readiness check times out before the service is up.
The wait timeout is too short for a cold start
A fixed, short timeout that works on a fast machine fails on a slower or loaded runner where the service’s cold start takes longer.
How to fix it
Give the readiness wait enough headroom
Raise the wait timeout to cover a realistic cold start, and poll rather than waiting a fixed time.
./wait-for-it.sh postgres:5432 -t 60 -- echo "db ready"
# or a bounded poll loop:
for i in $(seq 1 30); do nc -z postgres 5432 && break; sleep 2; doneRetry and verify the service actually starts
- Re-run the step - a transient slow start usually succeeds on retry.
- Check the service container’s own logs to confirm it boots (vs. crash-looping).
- Use a real health endpoint instead of just a port check where the service has one.
How to prevent it
- Set readiness timeouts to cover the service’s realistic cold start, not the average.
- Poll a health endpoint rather than sleeping a fixed amount.
- Surface dependent-service logs so a genuine startup failure is distinguishable from slowness.