Skip to main content
Fix "Cannot Connect to the Docker Daemon"

Fix "Cannot Connect to the Docker Daemon"

KU
• 6 min read•Updated •64 views

The daemon error almost never means Docker is broken. Nine times out of ten it's a stopped service, a stale context, or a wrong env var. Here's the checklist.

You run docker ps, expecting a list of containers, and instead get this:

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

I've hit this on fresh laptops, in CI runners, over SSH into boxes I'd forgotten I configured, and once on my own machine an hour after I'd installed Docker and walked away. The message reads like something is badly broken. It almost never is. The CLI is a thin client that talks to a daemon over a socket, and this error means the client couldn't reach that socket. That's it. Every fix below is about answering one question: which daemon should I be talking to, and is it up?

Work through these in order. The whole thing takes a couple of minutes and you'll usually be done by step two.

First, look at where the client is even pointing

Before touching services, check what the CLI thinks it should connect to. Two commands:

bash.bash
echo $DOCKER_HOST
docker context ls

If DOCKER_HOST is set to something you don't recognize (an old tcp:// address, a remote box that's long gone), that's your answer. I've seen this survive in a .bashrc from a tutorial someone followed two years ago. The CLI dutifully tries to reach a machine that no longer exists.

bash.bash
unset DOCKER_HOST

Then retry docker ps. If it works, go delete that export from your shell profile so it doesn't come back tomorrow.

docker context ls shows the same thing from the other side. The active context has a * next to it:

code
NAME              DESCRIPTION                   DOCKER ENDPOINT
default *         Current DOCKER_HOST based     unix:///var/run/docker.sock
desktop-linux     Docker Desktop                unix:///home/me/.docker/desktop/docker.sock

If the star is on a context whose endpoint points somewhere unreachable, switch back:

bash.bash
docker context use default

This one bites people who install Docker Desktop and later install the native engine, or vice versa. The context gets left pointing at a socket that isn't being served anymore. docker context use is the whole fix.

Then check whether the daemon is actually running

On a Linux host with the native engine, the daemon runs as a systemd service. Ask systemd directly:

bash.bash
systemctl status docker

If you see Active: inactive (dead) or failed, start it:

bash.bash
sudo systemctl start docker
sudo systemctl enable docker   # so it comes back after a reboot

I add the enable line because "it worked yesterday" after a reboot is the single most common way this error comes back. Fresh installs of the engine on some distros don't enable the service by default.

If the service refuses to start, it will loop in status. Don't guess at why. Read the logs:

bash.bash
journalctl -u docker --no-pager -n 40

The real cause is almost always in the last twenty lines. A corrupt daemon.json, a bad storage driver, a port already bound. I once spent ten minutes on a "mystery" that turned out to be a trailing comma in /etc/docker/daemon.json. The journal told me on line three; I just hadn't read it.

On Docker Desktop (Mac, Windows, or Linux), there's no systemd service to poke. The daemon lives inside Desktop's VM, and if Desktop isn't running, the socket isn't served. Open the app, wait for the whale icon to stop animating, then retry. Obvious, but it's caught me after a reboot more than once.

The socket is missing entirely

If ls -l /var/run/docker.sock returns "No such file or directory," no daemon has created it. That's the running-daemon problem above, not a separate bug. Start the service and the socket appears.

Permissions look like a connection error but aren't

There's a lookalike. If the daemon is up but your user isn't in the docker group, you get a permission-denied on the socket, which the CLI sometimes phrases close enough to the connection error to confuse you. Quick tell: sudo docker ps works but plain docker ps doesn't. If that's your situation, it's a group membership problem, and I've written up the Docker daemon permission fixes separately so I won't repeat them here.

Rootless and WSL2, the two setups that trip everyone

Rootless Docker doesn't use /var/run/docker.sock. It runs the daemon as your user, and the socket lives under your runtime dir:

bash.bash
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
systemctl --user status docker

Note the --user. Rootless is a user service, not a system one, so sudo systemctl will tell you nothing useful. If you set up rootless and then wonder why systemctl status docker says the unit doesn't exist, this is why.

WSL2 has its own trap. If you're running the Docker CLI inside a WSL2 distro and talking to Docker Desktop on Windows, that link is Desktop's WSL integration, and it's a per-distro toggle. Open Desktop, go to Settings, Resources, WSL Integration, and confirm your distro is switched on. When that toggle is off, the CLI inside WSL has no socket to reach and you get the exact daemon error. Flip it on, restart the shell.

The diagnosis flow, condensed

When I hit this cold, I run these four in a row before changing anything:

bash.bash
echo $DOCKER_HOST          # is the client aimed somewhere weird?
docker context ls          # is the active context sane?
systemctl status docker    # is the daemon actually up? (or --user for rootless)
journalctl -u docker -n 40 # if it won't start, why not?

That sequence separates the "client is pointed wrong" cases (the first two) from the "daemon is down" cases (the last two), and those two families cover essentially every instance of this error I've seen.

The call we'd make

Don't reinstall Docker. I've watched people nuke a working install over this error when the actual problem was a stale DOCKER_HOST in their shell. Check where the client points, confirm the daemon is up, read the journal if it won't start. The error is loud and the fix is usually one line. Treat it as a routing question, not a broken-engine question, and you'll close it in under two minutes.

Explore topics:DockerLinuxDevOps
React
Share this post
KU

Kiril Urbonas

AI Engineer

553 articles
View all articles by Kiril Urbonas

You might have missed

Evergreen posts worth revisiting.