KhueApps
Home/DevOps/Fix "Cannot connect to the Docker daemon" on Linux, macOS, and WSL2

Fix "Cannot connect to the Docker daemon" on Linux, macOS, and WSL2

Last updated: October 06, 2025

Overview

Error seen by the Docker CLI:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

This means the Docker client cannot talk to the daemon over the Unix socket. Common causes:

  • The daemon is not running.
  • Your user lacks permission to access /var/run/docker.sock.
  • Wrong Docker context or DOCKER_HOST environment variable.
  • Rootless vs rootful mismatch (Linux).
  • Stale/missing socket file or corrupted state.
  • Docker Desktop not running or WSL2 integration disabled (macOS/Windows).

Quickstart: fastest likely fixes

  • Linux (systemd):

    • Start and enable Docker
      sudo systemctl start docker
      sudo systemctl enable docker
      
    • Add your user to the docker group, then re-login
      sudo usermod -aG docker "$USER"
      newgrp docker  # temp re-evaluate groups in current shell
      docker version
      
  • macOS/Windows with Docker Desktop:

    • Ensure Docker Desktop is running and shows "Running".
    • Select a valid context
      docker context ls
      docker context use desktop-linux  # or: docker context use default
      docker version
      
  • WSL2 (Windows):

    • Restart WSL and Docker Desktop
      wsl --shutdown
      # then start Docker Desktop from the Start menu
      
    • Inside your WSL distro, verify the socket and context
      ls -l /var/run/docker.sock
      docker context use desktop-linux
      docker version
      
  • Reset an incorrect DOCKER_HOST:

    echo "$DOCKER_HOST"
    unset DOCKER_HOST
    docker version
    

Minimal working example

Once connectivity is fixed, this should succeed:

docker run --rm hello-world

Or verify daemon details:

docker info

Common causes and exact fixes

SymptomHow to checkFix
Daemon not runningsystemctl is-active docker (Linux)sudo systemctl start docker && sudo systemctl enable docker
Not in docker group`groupsgrep docker`
Wrong contextdocker context lsdocker context use desktop-linux (Desktop) or docker context use default
Wrong DOCKER_HOSTprintenv DOCKER_HOSTunset DOCKER_HOST or set to unix:///var/run/docker.sock
Stale socketls -l /var/run/docker.sock and `ps auxgrep dockerd`
Rootless mismatch`ps -u $USERgrep dockerdandsystemctl --user status docker`
Docker Desktop not runningTray/app statusLaunch Docker Desktop; wait until "Running"
WSL2 integration offDocker Desktop > Settings > Resources > WSL IntegrationEnable your distro; restart WSL: wsl --shutdown
Installed via snap (Linux)snap list dockerPrefer official packages; remove snap and install from repo; then restart

Step-by-step (Linux, systemd)

  1. Check daemon status and logs
systemctl status docker --no-pager
journalctl -u docker -b --no-pager | tail -200
  1. Start/enable service
sudo systemctl start docker
sudo systemctl enable docker
  1. Fix permissions (non-root usage)
sudo usermod -aG docker "$USER"
newgrp docker  # or log out and back in
  1. Verify the socket and ownership
ls -l /var/run/docker.sock
# expected: srw-rw---- root docker ... /var/run/docker.sock

If the socket exists but dockerd is not running, remove it and restart:

sudo rm -f /var/run/docker.sock
sudo systemctl restart docker
  1. Clear incorrect environment overrides
unset DOCKER_HOST DOCKER_CONTEXT
docker context use default
  1. Rootless vs rootful
  • If using rootless: ensure the user service is running and use the right socket
    systemctl --user start docker
    export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
    
  • If not using rootless: stop user service and unset DOCKER_HOST
    systemctl --user stop docker || true
    unset DOCKER_HOST
    sudo systemctl restart docker
    
  1. SELinux/AppArmor issues (Linux)
  • If you see "permission denied" on the socket: restore labels and restart
    sudo restorecon -v /var/run/docker.sock 2>/dev/null || true
    sudo systemctl restart docker
    

Step-by-step (Docker Desktop: macOS/Windows)

  1. Start Docker Desktop and wait for "Running".

  2. Select a valid context

docker context ls
docker context use desktop-linux  # or: default
  1. Restart Desktop if needed
  • macOS: Docker Desktop menu > Quit Docker Desktop, then reopen.
  • Windows: Right-click tray icon > Quit Docker Desktop, then reopen.
  1. Windows + WSL2 specifics
wsl --list --verbose   # Ensure your distro is version 2
wsl --shutdown         # Then restart Docker Desktop

In Docker Desktop, enable WSL integration for your distro. Inside WSL, confirm:

ls -l /var/run/docker.sock
docker run --rm hello-world

Diagnostics you can run

docker version
docker info
ps aux | grep dockerd | grep -v grep
sudo systemctl status docker --no-pager
journalctl -u docker -b --no-pager | tail -200
printenv | grep -E 'DOCKER_HOST|DOCKER_CONTEXT'
docker context ls

Pitfalls and gotchas

  • Forgetting to re-login after adding your user to the docker group.
  • Using sudo docker ... once and assuming non-root will work without group membership.
  • Leaving DOCKER_HOST set to a TCP or rootless socket when you intend the default Unix socket.
  • Mixing Docker Engine and other shims (e.g., podman-docker) causing unexpected sockets.
  • Stale /var/run/docker.sock file after crashes; remove it and restart the service.
  • On WSL2, running wsl --shutdown stops all distros; restart Docker Desktop afterward.

Performance and reliability notes

  • Enable service on boot so dockerd is ready when you log in:
    sudo systemctl enable docker
    
  • Optionally enable socket activation on some distros:
    sudo systemctl enable docker.socket
    
  • Avoid frequent restarts in scripts; check readiness once with docker info and back off on failure.
  • Keep Docker Desktop updated; older versions may expose different contexts.
  • On Linux, prefer the distribution or official Docker packages over snap for fewer permission surprises.

FAQ

  • Why does sudo docker ps work but docker ps fails?

    • Your user is not in the docker group. Add it and re-login.
  • How do I know which daemon I’m talking to?

    • Check docker context show, printenv DOCKER_HOST, and docker info | grep -i server.
  • Do I need to set DOCKER_HOST?

    • Usually no. The default local Unix socket is correct. Unset it unless you intentionally target a remote or rootless daemon.
  • Compose can’t connect either. Same fix?

    • Yes. docker compose uses the same client config and environment; once the CLI works, Compose should too.

Series: Docker

DevOps