Docker permission denied on docker.sock: the Right Fix (and Its Security Cost)
Symptom: works with sudo, denied without it
permission denied while trying to connect to the Docker daemon socket at
unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.sock/_ping":
dial unix /var/run/docker.sock: connect: permission denied
One-line diagnosis: the docker.sock socket file belongs to root:docker, and your user is neither root nor in the docker group. Docker is client/server: the CLI connects to the socket as your user, and the daemon-side check isn't about images or registries — it's "are you allowed to touch this socket".
Confirm the ownership:
ls -l /var/run/docker.sock
# srw-rw---- 1 root docker 0 ... /var/run/docker.sock
# ↑ owner root, group docker, no access for anyone else
The fix: add your user to the docker group (one step)
sudo usermod -aG docker $USER
newgrp docker # effective in the current terminal immediately, no logout
docker ps # try without sudo
newgrp only affects the current shell; for a full effect, log out and back in (group membership loads at login — su - $USER also works). Never drop the -a flag — -G docker without -a replaces your entire group list, and losing the sudo group locks you out of your own machine.
Three wrong fixes to avoid
1. chmod 777 /var/run/docker.sock
It works — and hands control of the daemon to every user on the machine. The socket gets recreated on daemon restart, reverting the permission, so the problem "mysteriously returns". Don't.
2. Permanent sudo docker ...
Works, with two costs: every docker artifact (volume data, build cache) defaults to root ownership, which your non-sudo scripts then can't read; and sudo sprinkled through CI scripts is harder to audit, not easier.
3. chown $USER /var/run/docker.sock
Same nature as 777 — you're changing the ownership of a system component, and it reverts on restart/upgrade.
The security cost you must know: docker group ≈ root
Joining the docker group grants an equivalent of passwordless root:
# Any docker-group user can get a root shell on the host like this
docker run -v /:/host -it alpine chroot /host sh
So: on a personal dev machine, joining the group is fine. On a multi-user production server, treat docker group grants with the same approval process as sudo. Safer alternatives:
- Rootless Docker: the daemon runs under your own user, the socket lives in
~/.config/docker— no permission problem, no privilege escalation (tradeoff: some features need extra setup, like binding ports below 1024); - Fine-grained access: a docker socket proxy (e.g. tecnativa/docker-socket-proxy) exposing only whitelisted API calls.
Neighboring errors that confuse people
| Error | Meaning | Direction |
|---|---|---|
| permission denied ... docker.sock | socket exists, you lack access | this post |
| Cannot connect to the Docker daemon | socket missing / daemon down | daemon post |
| permission denied (during pull) | registry auth failure | docker login, not this post |
The third one is the most misleading: it also says permission denied, but during docker pull — that's a private registry login issue, unrelated to socket permissions.
Checklist
ls -l /var/run/docker.sock— confirm group ownership is dockerid— does the group list include docker?- Not there →
sudo usermod -aG docker $USER && newgrp docker - In the group but still failing → log out and back in (groups refresh at login)
- Server scenario → read the "security cost" section before deciding
- Never use the chmod 777 / chown / permanent-sudo trap fixes
Provided by ToolVault. Related tools: Dockerfile Generator, Linux Cheatsheet. Related reading: Docker daemon unreachable, SSH Permission denied (publickey). See the homepage for more developer tools.
Related Tools
Related Articles
Permission denied (publickey): 6 Reasons Git Push Fails Over SSH (and the Fix for Each)
git clone or push rejected with Permission denied (publickey) fatal: Could not read from remote repository? Covers missing keygen, key not loaded in the agent, public key not added to GitHub/GitLab, multi-account key routing with ~/.ssh/config, deploy key limits, and wrong remote URLs — with ssh -v diagnostics.
error:0308010C digital envelope routines::unsupported — Fixing Node 17+ Breakage in Older Projects
Node 17+ crashes webpack 4 builds with error:0308010C:digital envelope routines::unsupported because OpenSSL 3.0 removed MD4. Three fixes compared: --openssl-legacy-provider quick unblock, upgrading to webpack 5 as the real fix, and pinning Node 16 as a stopgap.
ECONNREFUSED: Connection Refused — 5 Causes Explained (Including Docker)
Node, Java, or curl reporting connect ECONNREFUSED 127.0.0.1:3306? It means nothing is listening on that port. Covers service not running, wrong port, 127.0.0.1-only binding, Docker container networking, and firewall REJECT rules — with ss/lsof diagnostic commands.