Docker Permission Denied — Cannot Connect to the Daemon Socket
Fix permission denied on /var/run/docker.sock by checking group membership, socket ownership, Docker context, and rootless daemon paths before relaxing permissions.
Symptoms
- permission denied while trying to connect to the Docker daemon socket
- Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
- docker ps fails as a normal user but sudo docker ps works
- The same user works in one terminal session but not in a new SSH session
Possible causes
- The user is not a member of the docker group
- The group was added but the current login session still has the old group set
- The socket is owned by root with mode 660 and a rootless daemon uses a different socket path
- DOCKER_HOST or the active Docker context points at a socket the user cannot access
- A mounted docker.sock inside a container has different ownership than the process user
Diagnosis steps
Check the user's groups and the docker group members
id; getent group dockerInterpretation
If docker is missing from id output, the session has not picked up membership. If the user is listed in getent but absent from id, log out and back in.
Inspect socket ownership and mode
ls -l /var/run/docker.sock; stat -c '%a %U %G' /var/run/docker.sockInterpretation
A 660 root:docker socket works only for root and members of docker. A missing socket means the daemon or socket unit is not running.
Check which endpoint the CLI is actually using
docker context ls; echo "DOCKER_HOST=$DOCKER_HOST"Interpretation
An active rootless or remote context explains why the default socket permissions are irrelevant. Compare the endpoint path with the socket you inspected.
Check the daemon and socket unit state
systemctl status docker.socket docker.service; journalctl -u docker --no-pager -n 30Interpretation
A failed socket unit or an AppArmor denial in the journal points to a service problem rather than group membership.
Root cause
The Docker CLI could not open the Unix socket because the calling process lacked write permission, or because it was connecting to a different socket than the one inspected. Unix socket access follows file permissions, so membership in the owning group, the socket mode, and the selected Docker context all have to agree.
Fix
Add the user to the docker group with sudo usermod -aG docker $USER, then start a new login session or use newgrp docker for the current shell. Start the docker socket and service, and for rootless installations select the rootless context or set DOCKER_HOST to the per-user socket. Fix ownership through the systemd unit instead of chmod 777.
Risk note
Membership in the docker group is effectively root access because a member can mount the host filesystem into a container. Prefer rootless Docker for untrusted users. chmod 666 on the socket removes all access control, and recursively changing ownership of /var/run can break other services.
Verify the fix
Open a fresh login shell, confirm docker appears in id output, and run docker info and docker run --rm hello-world without sudo. Verify the context endpoint matches the socket path used by the daemon, and check the journal for new denials.
The CLI cannot open the socket
Docker on Linux exposes an API over a Unix socket, normally /var/run/docker.sock. Access is decided by ordinary file permissions: the process needs write permission on the socket. sudo docker ps working while docker ps fails is the classic signature of missing group membership.
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock:
Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
Check membership, then the session
id
getent group docker
ls -l /var/run/docker.sock
docker context ls
If getent group docker lists the user but id does not, the login session predates the group change. A new SSH session is required; newgrp docker only fixes the current shell. If the socket is missing entirely, the daemon or its socket unit is not running.
A different DOCKER_HOST or an active rootless context explains failures that survive re-login: the CLI is talking to another socket with its own permissions.
Grant access without weakening the host
sudo usermod -aG docker "$USER"
newgrp docker # current shell only
docker context use default
# rootless alternative:
# docker context use rootless
Rootless Docker runs the daemon as the user and uses $XDG_RUNTIME_DIR/docker.sock, which avoids the group entirely. Duplicate group entries after several usermod -aG runs are harmless but indicate sloppy onboarding; audit them with getent group docker.
Verify from a clean session
Open a new login shell, confirm id contains docker, and run docker info and docker run --rm hello-world without sudo. Also verify the CLI context points at the socket the daemon owns. If the error persists, read journalctl -u docker for AppArmor or SELinux denials before changing any permissions.