That error means the Docker client knocked on the Unix socket at /var/run/docker.sock and found nothing listening on the other end. The connection is refused at the filesystem level, so before you touch iptables or the CLI, confirm two things: the Docker daemon is actually running, and your user can reach that socket. On a Linux host the usual culprits are a stopped docker.service, a user outside the docker group, or a Docker Desktop context left pointing at a socket that WSL or a VM no longer exposes. Work through the seven fixes below in order; each one rules out a layer so you never reinstall Docker to solve a permissions problem.
Read the Error Literally: What "No Such File or Directory" Actually Confirms
The phrase "connect: no such file or directory" tells you the socket path doesn't exist at the moment of the call. That's different from "permission denied," which means the file exists but your user can't open it. The daemon either never created the socket or removed it when it stopped.
Daemon down: docker.service isn't running, so nothing is bound to the Unix domain socket. Wrong path: the client is configured to hit a socket that doesn't exist on this machine (common after copying a config file between hosts). Wrong environment: you're inside a container or WSL instance that can't see the host's socket.
Run ls -l /var/run/docker.sock first. If the file is absent, the problem is the daemon or the path. If it's present, jump straight to the permissions section. Docker's own documentation lists this error under the CLI troubleshooting page and points at the same two checks: daemon running, user in the right group.
Step 1: Confirm the Docker Daemon Is Running
On systemd-based Linux, sudo systemctl status docker gives you the live state, the unit file path, and the last few log lines in one command. A healthy output reads "active (running)" and shows a PID. Anything else β "inactive (dead)," "failed," or "activating" stuck in a loop β points at the daemon, not the socket.
Start it with sudo systemctl start docker and immediately re-check the status. If it fails within seconds, read the journal: sudo journalctl -u docker --no-pager -n 50 shows why. Typical failure lines include "failed to start daemon: pid file found, ensure docker is not running" or a storage driver error such as "overlay2: backing file system is not supported," which happens when Docker's data directory sits on a filesystem that can't support overlayfs.
If you're not on systemd β older Debian, some Alpine hosts, or a bare init β use sudo service docker start or sudo dockerd foreground to watch startup output live. Running dockerd in the foreground is the fastest way to see the exact error the daemon throws before it gives up.
Step 2: Verify the Socket Path and Docker Context
Before assuming the daemon is broken, confirm the client is looking at the right place. docker context ls prints every configured context and marks the active one with an asterisk. Docker Desktop on Windows and macOS creates a context named desktop-linux that points at a socket inside a VM, not at /var/run/docker.sock. If you installed Desktop and later moved to native Linux, the stale context produces exactly this error.
Switch back with docker context use default, then re-run docker info. You can also override the endpoint per command: docker -H unix:///var/run/docker.sock ps. That flag is handy for testing without changing global state.
Check the DOCKER_HOST environment variable with echo $DOCKER_HOST. If it's set to tcp://127.0.0.1:2375 on a machine where the daemon only listens on the Unix socket, you'll get a connection error that looks similar but names a TCP address instead. Unset it with unset DOCKER_HOST and test again. The environment variable overrides the context, so a leftover export in .bashrc can quietly break a working install for months.
Step 3: Fix Socket Permissions and the Docker Group
A socket that exists but rejects your user returns "permission denied," not "no such file." Still, verify the group membership because a misconfigured group can produce odd failures when tools try fallback paths. On Ubuntu and Debian, the installer usually creates a docker group with the socket owned root:docker and mode 0660. On Fedora and RHEL, the same group exists but you may not be in it.
Run these in order:
1: ls -l /var/run/docker.sock to confirm the owner and group. 2: groups to check whether your user is a member. 3: sudo usermod -aG docker $USER to add yourself. 4: Log out and back in β group changes don't apply to an existing shell. 5: docker ps to confirm.
The group membership requires a full session restart, not just a new terminal tab, in most desktop environments. If docker ps still fails after re-login, run newgrp docker in that shell to pick up the group immediately.
Step 4: Rule Out a Container Trying to Reach the Host Socket
Running Docker commands inside a container that doesn't mount the host socket produces this error too. The container has no /var/run/docker.sock unless you explicitly bind-mount it with -v /var/run/docker.sock:/var/run/docker.sock. That's correct behavior, not a bug.
Mounting the socket into a container grants root-equivalent host access, so treat it as a serious privilege escalation when the container image isn't trusted. For build pipelines that need Docker-in-Docker, prefer the dedicated docker:dind image running its own daemon over host socket passthrough. If you genuinely need the socket inside a container β common with local CI runners β restrict the mount to a specific named container and drop other capabilities.
Step 5: Restart the Socket via systemd Socket Activation
Docker ships a companion unit called docker.socket that creates /var/run/docker.sock and hands it to the daemon on first connection. If the socket unit is masked or disabled, the daemon may run but never publish the socket. Check with systemctl status docker.socket and enable it with sudo systemctl enable --now docker.socket.
After any change to the socket unit, restart both:
sudo systemctl daemon-reload sudo systemctl restart docker.socket docker
If you edited /etc/systemd/system/docker.service.d/*.conf overrides, daemon-reload is mandatory or the change won't apply. A subtle failure: an override that sets ExecStart= with a different socket path, so the daemon listens at /run/docker.sock while clients still look at /var/run/docker.sock. On most distros those are the same inode via symlink, but not always.
Step 6: Check Rootless Docker and Desktop-on-WSL Setups
Rootless Docker runs the daemon as your user and puts the socket at $XDG_RUNTIME_DIR/docker.sock, typically /run/user/1000/docker.sock. If you installed rootless mode and forgot to set DOCKER_HOST, the client defaults to /var/run/docker.sock β which rootless mode never creates. Set it in your shell profile: export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock.
On WSL2 with Docker Desktop, the socket lives inside the Desktop VM. WSL integration must be enabled per distribution in Docker Desktop's Settings β Resources β WSL Integration. When it's off, the Linux shell has no socket and you get the file-not-found error. Toggle it on, restart the WSL distro with wsl --shutdown from PowerShell, and re-open.
| Environment | Socket path | Typical default client path | Fix |
|---|---|---|---|
| Native Linux (rootful) | /var/run/docker.sock | /var/run/docker.sock | Start docker.service |
| Rootless Linux | /run/user/1000/docker.sock | /var/run/docker.sock | Export DOCKER_HOST |
| Docker Desktop (macOS/Windows) | Inside the VM | Context desktop-linux | docker context use desktop-linux |
| Docker Desktop + WSL2 | VM via WSL integration | /var/run/docker.sock | Enable WSL integration |
| Docker-in-Docker container | Container-internal socket | /var/run/docker.sock | Use docker:dind, no host mount needed |
Step 7: Reinstall Only After You've Excluded the Above
Reinstalling Docker is the last resort and almost never fixes this error, because the socket problem is configuration, not binaries. If the daemon binary itself is broken β dockerd --version fails or returns a loader error β reinstall via the official repo. On Ubuntu: sudo apt-get remove docker docker-engine docker.io containerd runc, then add Docker's apt repo and sudo apt-get install docker-ce docker-ce-cli containerd.io.
Back up /var/lib/docker before removal if you have images worth keeping. A fresh package install recreates systemd units and the socket unit cleanly, which occasionally resolves a masked or overridden unit left behind by an older version. If you migrate from docker.io (the distro package) to docker-ce, the two packages conflict β remove one before installing the other.
Error Variants and What Each One Signals
The full text varies by OS and Docker version, and each variant nudges you toward a different layer.
| Full error substring | Meaning | First command to run |
|---|---|---|
| no such file or directory | Socket absent β daemon not running or wrong path | systemctl status docker |
| permission denied | Socket present, user not authorized | groups / usermod -aG docker |
| connection refused | Nothing listening on a TCP port | echo $DOCKER_HOST |
| operation not permitted | Firewall or seccomp blocking the call | Check iptables, container seccomp |
| context deadline exceeded | Daemon hung or VM paused | systemctl restart docker |
The "permission denied" variant is the single most common follow-up question. It happens after a fresh install when the user is added to the docker group but hasn't restarted their session. If you see it and "no such file," the shell is hitting a stale path.
Preventive Setup: Stop It Happening Again
Enable the daemon at boot with sudo systemctl enable docker, so a reboot doesn't leave you socket-less. Add your user to the docker group once during initial setup and verify it in a fresh login. Pin DOCKER_HOST nowhere unless you actually need a remote daemon β leaving it unset keeps the client on the local context.
For teams, bake these checks into onboarding scripts. A single docker info >/dev/null 2>&1 || { echo "Docker daemon unreachable"; exit 1; } at the top of a setup script catches the failure before a longer build wastes time. Treat the socket as a privileged endpoint: mode 0660, root:docker, never world-writable.
Troubleshooting Checklist You Can Paste into a Terminal
Run these in sequence and stop at the first failure β it's your layer.
1: ls -l /var/run/docker.sock β exists? 2: sudo systemctl status docker docker.socket β active? 3: echo $DOCKER_HOST β unexpectedly set? 4: docker context ls β which context is active? 5: groups | grep docker β are you in the group? 6: sudo journalctl -u docker -n 30 β what does the log say? 7: sudo dockerd β run foreground to see the exact startup error.
Each command isolates one variable, so you never chase the wrong cause. The first three take under ten seconds and resolve the majority of cases.
FAQ
Does restarting the machine fix the missing socket error?
Sometimes, because a reboot re-runs systemd and recreates the socket if the unit is enabled. That's a symptom patch, not a diagnosis. If the socket disappears on every reboot, docker.socket is disabled β run sudo systemctl enable docker.socket so it's recreated automatically rather than relying on a manual restart.
Why do I get "permission denied" instead of "no such file directory"?
Permission denied means the socket exists but your user can't open it, usually because you're not in the docker group or the group hasn't applied to your current shell. It's a later stage than the missing-file error, which means the socket wasn't created at all. Add yourself to the group and start a fresh login session.
Is it safe to chmod 777 /var/run/docker.sock?
No. Making the socket world-writable lets any local process run containers with root-equivalent host access, and Docker's own security guidance warns against it. Use mode 0660 with group ownership and proper group membership. Setting 777 is a guaranteed privilege-escalation hole on shared machines.
Can rootless Docker fix this error?
Rootless mode relocates the socket to /run/user//docker.sock, so it resolves the error only if you also point the client there with DOCKER_HOST. Without that export, rootless users hit the same file-not-found error. Rootless trades some networking and port-binding convenience for running the daemon without root.
What's the difference between this and "Cannot connect to the Docker daemon at tcp://..."?
The TCP variant means the client is configured to reach a remote or TCP-exposed daemon, and either DOCKER_HOST or a context points there. The Unix-socket message means local IPC failed. Check docker context ls and echo $DOCKER_HOST to see which transport is active.
Why does Docker Desktop on WSL2 keep losing the socket?
WSL integration is per-distribution and gets reset on Docker Desktop upgrades or WSL version changes. Re-enable it under Settings β Resources β WSL Integration, then run wsl --shutdown from PowerShell. Upgrading WSL2 without restarting Docker Desktop is the most common trigger.
Do I need to reinstall Docker if none of the fixes work?
Rarely. The socket failure is almost always a configuration issue β stopped unit, wrong context, missing permissions, or rootless misconfiguration. Reinstall only when dockerd --version itself fails or the binary is corrupt, and back up /var/lib/docker first.