Fix "Cannot Connect to the Docker Daemon
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.
Key takeaways
- 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.
On this page
Fix "Cannot Connect to the Docker Daemon"#
You run docker ps, expecting a list of containers, and instead get this:
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:
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.
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:
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:
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:
systemctl status docker
If you see Active: inactive (dead) or failed, start it:
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:
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:
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:
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.
Get the DevOps Troubleshooting Cheat Sheet
Subscribe and get our free one-page reference for the errors that eat an afternoon — CrashLoopBackOff, OOMKilled, Terraform state locks, and more — plus new guides as we publish them.
AWS Graviton Migration: What Broke and What We Saved
Moving our fleet from x86 to Graviton promised 20% savings. We got 31%, but only after fixing native dependencies, a broken base image, and one nasty perf regression.
GitHub Actions Best Practices in 2026: Workflows You Can Trust
A production-focused GitHub Actions guide: reusable workflows, least-privilege permissions, keyless OIDC to the cloud, SHA-pinned actions, environments with approvals, concurrency-safe deploys, and CodeQL/Dependabot gates — with copy-paste examples.
More from DevOps
Explore more articles in this category
Best Kubernetes IDE and GUI Tools in 2026
kubectl is fine until you're juggling five namespaces across three clusters. These are the tools that make that manageable, compared.
Chef vs Puppet vs Ansible: Configuration Management in 2026
One is agentless and Python-based, the other two run a persistent agent and a domain-specific language. The architecture difference matters more than the syntax.
PagerDuty vs Opsgenie: Choosing an Incident Alerting Tool
Both page the right person at 3am and both integrate with everything. The real differences show up in pricing structure, workflow depth, and who already owns the ecosystem around you.
You might have missed
Evergreen posts worth revisiting.