Meta Description: I hit the Docker permission denied error more times than I’d like to admit. Here’s every fix I’ve used on Ubuntu, from quick patches to root causes.
The first time I saw permission denied while trying to connect to the Docker daemon socket, I did what most people do — I just typed sudo in front of every Docker command and moved on with my day. That worked, until it didn’t. A few weeks later I was debugging a broken CI script that couldn’t use sudo, file ownership issues from containers writing root-owned files into my project folder, and a Docker Desktop install that kept throwing the same error even after I “fixed” it once already.
After going through this cycle enough times across different Ubuntu machines and server setups, I’ve got a clear picture of why this error happens and — more importantly — how to fix it properly instead of just papering over it with sudo. That’s what I’m walking through here.
Why “Docker Permission Denied” Happens in the First Place
Docker runs as a background daemon (dockerd), and by default, that daemon listens on a Unix socket at:
/var/run/docker.sock
This socket is owned by root and a special group called docker. When you run a Docker command, the Docker CLI talks to that socket. If your user account isn’t a member of the docker group, the kernel blocks the connection — hence the permission denied error.
This is a deliberate security decision, not a bug. Anyone with access to the Docker socket effectively has root-equivalent access to the host machine, since containers can be configured to mount the host filesystem. Ubuntu (and Docker’s own install docs) intentionally don’t put you in that group automatically.
The Standard Fix: Add Your User to the Docker Group
This solves the error for the vast majority of people, and it’s the fix I recommend starting with.
Step 1 — Check If the Docker Group Exists
getent group docker
If it returns nothing, create it:
sudo groupadd docker
Step 2 — Add Your User to the Group
sudo usermod -aG docker $USER
The -aG flags matter here: -a (append) ensures you’re added to this group without being removed from your other groups, and -G specifies the group. I’ve seen people accidentally drop the -a and get logged out of groups they needed — always include both flags.
Step 3 — Apply the Group Change
This is the step almost everyone gets wrong. Adding yourself to a group doesn’t take effect in your current shell session — Linux only reads group membership when a session starts.
newgrp docker
newgrp docker starts a new shell with the updated group applied immediately, without requiring a full logout. For it to apply everywhere (new terminal windows, SSH sessions, GUI apps), log out and log back in, or reboot if you’re on a desktop environment.
Step 4 — Confirm It Worked
docker run hello-world
If this runs without sudo and without a permission error, you’re done.
groups $USER
This should now list docker among your groups.
When the Standard Fix Doesn’t Work
In my experience, if adding yourself to the docker group didn’t fix it, the cause is almost always one of these four things.
1. You Didn’t Actually Start a New Session
This is the single most common reason the fix “doesn’t work.” Running usermod updates /etc/group, but your currently open terminal, tmux session, or SSH connection was authenticated before that change. Close the terminal completely (not just open a new tab in some cases) or run:
newgrp docker
or fully log out of your Ubuntu session and back in.
2. Docker.sock Has Incorrect Ownership
Occasionally, especially after a manual Docker install or a botched upgrade, the socket itself ends up with the wrong group ownership.
ls -l /var/run/docker.sock
You should see something like:
srw-rw---- 1 root docker 0 Jul 29 10:15 /var/run/docker.sock
If the group isn’t docker, fix it manually and restart the daemon:
sudo chown root:docker /var/run/docker.sock
sudo systemctl restart docker
Keep in mind this is a temporary fix — if the socket keeps resetting to the wrong owner on every restart, the real problem is usually in a custom docker.service override or a misconfigured daemon.json.
3. Docker Daemon Isn’t Running
Sometimes the actual error isn’t a permissions problem at all — it just looks like one because the socket doesn’t exist.
sudo systemctl status docker
If it’s inactive:
sudo systemctl start docker
sudo systemctl enable docker
4. You’re Using Docker Desktop, Not Docker Engine
On Ubuntu, Docker Desktop uses a different socket path and a different permission model than the standard Docker Engine install. If you’ve installed both at different points (common if you followed multiple tutorials), your CLI might be pointing at the wrong context.
docker context ls
Switch to the correct one:
docker context use default
I ran into this exact conflict after installing Docker Desktop on top of an existing Docker Engine setup, and switching context was the actual fix — not another round of usermod.
Comparing Your Fix Options
| Method | Effort | Security Impact | When I’d Use It |
|---|---|---|---|
Add user to docker group | Low | Grants root-equivalent access to that user | Local dev machines, personal workstations |
Always run with sudo | None | No group change needed, but clutters scripts | One-off commands, shared/locked-down machines |
| Fix socket ownership manually | Medium | Same as group fix, just applied directly | After a broken install or manual daemon config |
| Rootless Docker mode | High | Meaningfully more secure — no root daemon at all | Servers, security-sensitive environments, CI runners |
The More Secure Option: Docker Rootless Mode
If the reason you’re avoiding sudo docker is a security concern rather than just convenience, adding yourself to the docker group doesn’t actually solve that — it just moves the risk. Membership in the docker group is functionally equivalent to passwordless root, since you can mount the host’s root filesystem into a container and read/write anything.
For environments where that matters (build servers, CI runners, multi-user machines), I’d recommend Docker’s rootless mode, which runs the daemon itself as a non-root user.
# Install prerequisites
sudo apt-get install -y uidmap dbus-user-session
# Install rootless Docker
curl -fsSL https://get.docker.com/rootless | sh
After installation, you’ll need to add the printed environment variables (DOCKER_HOST, PATH) to your .bashrc or .zshrc. This mode has some tradeoffs — certain networking features and low port binding (below 1024) require extra configuration — but for CI and shared environments, it’s the option I trust the most.
Fixing Permission Errors on Files Created by Containers
A related but different problem I run into constantly: containers writing files as root inside a mounted volume, which then can’t be edited by your regular user on the host.
# Files created inside the container show up as root-owned on the host
ls -l ./output
# -rw-r--r-- 1 root root 1024 output.log
The cleanest fix is running the container process as your own UID/GID instead of root:
docker run --user "$(id -u):$(id -g)" -v "$(pwd)/output:/app/output" my-image
I add this flag by default now on any container that writes to a mounted volume — it’s saved me from a lot of sudo chown -R cleanup over the years.
Common Mistakes I See (and Made Myself)
| Mistake | Why It’s a Problem | Fix |
|---|---|---|
Forgetting to log out/in after usermod | Group change doesn’t apply to open sessions | Use newgrp docker or restart the session |
Running everything with sudo long-term | Root-owned files, messy permission history | Use the docker group or rootless mode |
| Assuming it’s always a group issue | Sometimes it’s the daemon not running, or wrong context | Check systemctl status docker and docker context ls |
| Not checking socket ownership after a manual install | Socket can end up owned by the wrong group | ls -l /var/run/docker.sock |
| Ignoring container-created root files | Breaks host-side editing of mounted volumes | Use --user "$(id -u):$(id -g)" |
Checklist: Resolving Docker Permission Denied on Ubuntu
- [ ] Confirmed the
dockergroup exists (getent group docker) - [ ] Added user to the group (
sudo usermod -aG docker $USER) - [ ] Started a new session (
newgrp dockeror full logout/login) - [ ] Verified group membership (
groups $USER) - [ ] Confirmed daemon is running (
systemctl status docker) - [ ] Checked socket ownership (
ls -l /var/run/docker.sock) - [ ] Verified correct Docker context if using Docker Desktop
- [ ] Considered rootless mode for CI/shared/security-sensitive machines
- [ ] Using
--user "$(id -u):$(id -g)"for containers writing to mounted volumes
FAQ
1. Why do I get “permission denied” when running Docker without sudo on Ubuntu? Because your user account isn’t a member of the docker group, which owns the Unix socket the Docker CLI uses to talk to the daemon. Adding your user to that group and starting a new session fixes it in almost all cases.
2. I added myself to the docker group but I’m still getting the error. What’s wrong? Most likely you haven’t started a new session yet. Group membership changes only apply to new logins. Run newgrp docker, or fully log out and back in, then try again.
3. Is it safe to just use sudo with every Docker command instead? It works, but it’s not a real fix — it just avoids the group change while adding friction to scripts, aliases, and CI pipelines that can’t easily use sudo. For a dev machine it’s a fine short-term workaround; long-term, fix the group membership or use rootless mode.
4. Is adding my user to the docker group a security risk? Yes, to some degree. Docker group membership is roughly equivalent to passwordless root access, since containers can mount and modify the host filesystem. On personal dev machines this is generally an acceptable tradeoff; on shared servers or CI runners, rootless Docker is the safer choice.
5. Why do files created by a container show up as owned by root on my host? Docker containers run as root by default, so anything the container writes to a mounted volume inherits root ownership on the host. Run the container with --user "$(id -u):$(id -g)" to have it write files as your own user instead.
6. How do I check if the Docker daemon is actually running? Run sudo systemctl status docker. If it shows inactive or failed, start it with sudo systemctl start docker and enable it on boot with sudo systemctl enable docker.
7. What’s the difference between Docker Engine and Docker Desktop permission handling on Ubuntu? Docker Engine uses the standard /var/run/docker.sock and the docker group. Docker Desktop manages its own context and socket path, and mixing both installs on the same machine can cause the CLI to point at the wrong context, producing permission-like errors that aren’t actually group issues.
Final Thoughts
The Docker permission denied error looks intimidating the first time you see it, but it almost always comes down to one root cause: your user session hasn’t picked up the docker group membership yet. Once you understand that the socket, the group, and the session lifecycle are the three moving parts here, debugging any variation of this error gets a lot faster — whether it’s a fresh install, a broken upgrade, or a Docker Desktop and Docker Engine conflict on the same machine.
If this helped you get unstuck, take a look at more of my Docker, Linux, and DevOps troubleshooting guides here on SpiritCode.blog — I write these based on real problems I’ve hit in actual production and development environments, not just documentation summaries.

