# Cannot connect to the Docker daemon

Classification: environment
Frameworks: Docker, CI
Canonical: https://automationtester.in/failures/docker-cannot-connect-to-daemon

## Recognizable error

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

## What it means

The Docker client found the socket it was told to use, but no daemon accepted the connection. The client's wording tells you which of three states you are in, so read it before restarting anything.

## Minimal repro

Run on 2026-10-23 with Docker CLI 29.2.1, colima 0.10.0 (Docker Engine 29.2.0), macOS, arm64.

make a socket file nobody listens on:

```shell
python3 -c "import socket; s = socket.socket(socket.AF_UNIX); s.bind('stale-docker.sock'); s.close()"
```

command:

```shell
DOCKER_HOST=unix://stale-docker.sock docker ps
```

output:

```text
Cannot connect to the Docker daemon at unix://stale-docker.sock. Is the docker daemon running?

# Same client, the default socket, which does not exist on this Mac:
failed to connect to the docker API at unix:///var/run/docker.sock; check if the path is correct and if the daemon is running: dial unix /var/run/docker.sock: connect: no such file or directory

# Same client, the stale socket after chmod 000:
permission denied while trying to connect to the docker API at unix://stale-docker.sock
```

## Ranked causes, checks, and fixes

### 1. The daemon is not running

The socket file is left behind, but dockerd, Docker Desktop or the colima VM behind it is stopped, or a docker:dind job never started its daemon. The moby client maps connection refused on an existing socket to exactly this message.

Diagnostic: Run `docker context ls` to see the endpoint, then `docker info`; on Linux check the docker service status, and in a dind setup check that the daemon container is up.

Fix: Start the daemon the endpoint belongs to, or in CI run Docker as a service the job waits on.

### 2. The client points at the wrong endpoint

DOCKER_HOST and DOCKER_CONTEXT override the context chosen with docker context use. docker context ls does warn that DOCKER_HOST overrides the active context, but docker ps and docker run only print the connection error. On the Mac we re-ran this on, DOCKER_HOST was exported in the shell, and docker context ls printed that warning under its table of contexts.

Diagnostic: Print DOCKER_HOST and DOCKER_CONTEXT in the failing shell or step and compare them with the running daemon's socket.

Fix: Unset the override or point it at the live socket. Here, setting DOCKER_HOST to the running profile's socket made `docker version` print client 29.2.1 server 29.2.0.

### 3. The job runs where there is no Docker

GitHub Actions supports service containers, container jobs and Docker container actions only on Linux runners; on GitHub-hosted runners that means Ubuntu. A job inside a container without the host socket mounted has no daemon either.

Diagnostic: Check runs-on and whether the step runs inside a container, and whether /var/run/docker.sock exists there.

Fix: Run Docker-dependent jobs on an Ubuntu runner, or mount the socket or a dind service into the job container deliberately.

## Verified fix

Point the client at a daemon that is running.

shell:

```shell
docker context ls
# Use the endpoint of the context whose daemon is running:
DOCKER_HOST=unix://$HOME/.colima/<running-profile>/docker.sock docker version
```

Evidence: Re-run on 2026-10-23 with Docker CLI 29.2.1: the stale socket gave the Cannot connect message, and pointing DOCKER_HOST at ~/.colima/default/docker.sock, the profile colima list showed as Running, made `docker version` print client 29.2.1 server 29.2.0. The default /var/run/docker.sock does not exist on that Mac, so the default endpoint gave the no such file or directory message instead, not this one. macOS caps a socket path at 104 bytes, which is why the repro binds a relative path: a long absolute one fails with unix socket path ... is too long.

## When this is not the cause

- **The socket path is wrong.** A path with no file behind it gives a different message from Docker CLI 29.2.1: failed to connect to the docker API at … check if the path is correct. Fix the path or context; restarting a daemon will not help.
- **Permissions.** permission denied while trying to connect to the docker API means a daemon may be fine and your user cannot open the socket. On Linux that is docker group membership, which Docker's docs warn grants root-level privileges.
- **Image or registry problems.** Pulls, rate limits and build errors all happen after a connection. With this message the client never reached a daemon at all.

## Prevention

- Do not set DOCKER_HOST globally in shell profiles; use contexts.
- Make Docker-dependent CI jobs declare an Ubuntu runner or a dind service explicitly.
- Fail early with `docker info` before tests that need containers.

## Primary references

- [moby source: client/request.go, which message for which failure](https://github.com/moby/moby/blob/master/client/request.go)
- [moby source: client/errors.go, the Cannot connect message](https://github.com/moby/moby/blob/master/client/errors.go)
- [Docker Docs: contexts, and DOCKER_HOST overriding them](https://docs.docker.com/engine/manage-resources/contexts/)
- [Docker Docs: Linux post-install, the docker group](https://docs.docker.com/engine/install/linux-postinstall/)
- [GitHub Docs: service containers need Linux runners](https://docs.github.com/en/actions/tutorials/use-containerized-services/use-docker-service-containers)

Triage this failure locally: https://automationtester.in/tools/test-failure-triage