Skip to content
Latchkey

Self-Healing CI: Recovering a Docker Daemon Not Ready at Start

When the first docker command runs before the daemon has finished starting, the build is fine - it just got there a second early. A brief wait-and-retry clears it.

The problem

The first docker command in a job fails with Cannot connect to the Docker daemon. Docker is installed and configured; the job simply started talking to the daemon before it finished coming up. A human re-runs the job, or adds a short readiness wait, and it connects cleanly.

Typical symptom
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Why it happens

On a freshly started runner, the Docker daemon takes a moment to initialize its socket and become ready to accept connections. A job that issues a docker command in that first instant races the daemon’s startup and gets a connection error.

It is a pure timing race, not a misconfiguration: the same command succeeds a second later once the daemon is listening, with no change to the job.

The manual fix

The manual fix is to wait for the daemon to be ready before the first command:

  1. Re-run the job (by the retry, the daemon is usually up).
  2. Add a short readiness loop that polls docker info until it succeeds before the first real docker command.
  3. Ensure the runner image starts the Docker service early in boot.
Manual readiness wait
for i in $(seq 1 30); do docker info >/dev/null 2>&1 && break; sleep 1; done
docker build .

How this gets automated

A "daemon not ready" error at job start has a clear startup-race signature, and the safe response is to wait briefly and retry. A self-healing CI pipeline detects the daemon-unavailable condition, waits for readiness, retries the step, and only escalates if the daemon never comes up - which is the real signal of a broken runner rather than a startup race.

Related guides

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