Skip to content

Fix: Cannot Connect to the Docker Daemon. Is the Docker Daemon Running?

FixDevs · (Updated: )

Part of:  Docker, DevOps & Infrastructure

Quick Answer

How to fix the 'Cannot connect to the Docker daemon' error on Linux, macOS, and Windows, including Docker Desktop, systemctl, WSL2, and Docker context issues.

The Error

You run a Docker command and get:

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

Or a variation like:

Cannot connect to the Docker daemon at tcp://localhost:2375. Is the docker daemon running?
Error response from daemon: dial unix /var/run/docker.sock: connect: no such file or directory

Every docker CLI command fails. You can’t build, run, pull, or do anything until the daemon is reachable.

Why This Happens

The Docker CLI is a client. It doesn’t run containers itself. It sends requests to the Docker daemon (dockerd), a background process that manages images, containers, networks, and volumes.

When you see “Cannot connect to the Docker daemon,” it means the CLI tried to reach the daemon and failed. The most common reasons:

  • The Docker daemon isn’t running. It was never started, it crashed, or the system rebooted and Docker isn’t set to start automatically.
  • The Docker socket doesn’t exist. The daemon creates /var/run/docker.sock when it starts. If the file is missing, the daemon isn’t running or was configured to use a different socket.
  • Wrong Docker context. The CLI is pointing to a remote host or a different socket path that isn’t available.
  • Docker Desktop isn’t open. On macOS and Windows, Docker runs inside a VM managed by Docker Desktop. If the application isn’t running, the daemon isn’t either.
  • WSL2 integration is broken. On Windows, Docker Desktop exposes the daemon to WSL2 distros through a special integration layer. If that layer is misconfigured, WSL2 can’t reach the daemon.
  • Permission issues. The socket exists but your user can’t access it. This produces a slightly different error, but sometimes manifests as a connection failure.
  • Snap vs apt installation conflicts. On Ubuntu, installing Docker via snap uses a confined environment with different socket paths, which can conflict with tools expecting the standard path.

The error string itself (“Cannot connect to the Docker daemon…”) has been stable for years, but the install model, license terms, and default build engine have all shifted. Knowing which Docker era you are on changes which fix applies.

Version History That Changes the Failure Mode

Docker’s surface area looks similar across releases, but several major changes have altered how the daemon is packaged, licensed, and started. If you copied an install guide from before 2021, expect mismatches.

  • Docker Engine 20.10 (Dec 2020) made rootless mode GA. Before 20.10, rootless was experimental and the socket path was different. If you are on a 19.x install pulled from an old distro repo, upgrade before debugging — many error patterns simply do not apply.
  • Docker Desktop license change (Aug 2021) moved Docker Desktop to a paid subscription for organizations with more than 250 employees or $10M+ revenue. Small teams and personal use stayed free. Some sysadmins reacted by removing Docker Desktop and installing Docker Engine alone, which is why you see machines today that have a docker CLI but no daemon running — the CLI was kept, but the Desktop VM that provided the daemon was uninstalled.
  • Docker Desktop on Linux (May 2022) brought the same VM-based install model to Linux. This is also when “two daemons on one Linux box” became a common failure pattern: the native dockerd from apt and the VM-managed daemon from Docker Desktop both claim sockets, and the CLI picks whichever context is active.
  • BuildKit became the default builder in Docker Engine 23.0 (Feb 2023). The legacy builder still exists but is opt-in. If you see DOCKER_BUILDKIT=0 exported somewhere in your shell config, that is a leftover from pre-23.0 workflows and may interact oddly with newer daemon behavior.
  • Docker Engine 24 (Jun 2023) reorganized internals and tightened how containerd is consumed. If you upgraded from 20.x straight to 24+, the containerd service might be missing or masked — check both with systemctl status.
  • Compose v2 became the default (the docker compose plugin replacing the standalone docker-compose Python script). If your scripts still call docker-compose and your install only ships docker compose, the command is “not found” and tools downstream of it can incorrectly report the daemon as down.
  • Compose Bridge (announced 2024) added Kubernetes manifest generation, but it requires a running daemon to function. If you script Compose Bridge in CI without a daemon, the error wording overlaps with daemon-not-running messages.

docker version, docker info, and docker context ls together tell you almost everything you need to identify the install pattern.

Fix 1: Start the Docker Daemon (Linux with systemd)

On most Linux distributions, Docker runs as a systemd service. Start it:

sudo systemctl start docker

Check its status:

sudo systemctl status docker

You should see active (running). If it shows inactive or failed, the daemon didn’t start. Check the logs:

sudo journalctl -u docker.service --no-pager -n 50

Common reasons for startup failure include corrupted storage drivers, misconfigured /etc/docker/daemon.json, or disk space issues.

To make Docker start automatically on boot:

sudo systemctl enable docker

This creates a symlink so systemd launches Docker on every reboot. If you’ve been having issues with systemctl services failing in general, check that the Docker unit file isn’t masked:

sudo systemctl unmask docker

Fix 2: Start Docker Desktop (macOS and Windows)

On macOS, Docker runs inside a Linux VM managed by Docker Desktop. The daemon isn’t a system service you start with systemctl. Open the Docker Desktop application from your Applications folder or the menu bar.

On Windows, the same applies. Launch Docker Desktop from the Start menu. Wait for the whale icon in the system tray to stop animating, meaning the VM and daemon are ready.

If Docker Desktop is already open but the daemon is unreachable:

  1. Right-click the Docker icon in the system tray (Windows) or menu bar (macOS).
  2. Click Restart.
  3. Wait for the status to show “Docker Desktop is running.”

Pro Tip: On macOS, you can also start Docker Desktop from the terminal without opening the GUI:

open -a Docker

This launches the app in the background. Give it 10-20 seconds to initialize the VM before running Docker commands.

On Windows, you can start it via PowerShell:

Start-Process "C:\Program Files\Docker\Docker\Docker Desktop.exe"

Fix 3: Fix WSL2 Integration (Windows)

If you’re running Docker commands inside a WSL2 terminal on Windows, the CLI needs Docker Desktop’s WSL2 integration to reach the daemon. Without it, the socket doesn’t exist inside your WSL2 distro.

  1. Open Docker Desktop.
  2. Go to Settings (gear icon).
  3. Navigate to Resources > WSL Integration.
  4. Enable integration for your WSL2 distro (e.g., Ubuntu).
  5. Click Apply & Restart.

After restarting, open a new WSL2 terminal and test:

docker info

If it still fails, restart WSL entirely from PowerShell:

wsl --shutdown

Then reopen your WSL2 terminal and try again.

Common Mistake: Running sudo systemctl start docker inside WSL2 when Docker Desktop is your Docker provider. WSL2 distros don’t run systemd by default (though newer versions can). If Docker Desktop is installed, use WSL2 integration instead of trying to run a separate daemon inside WSL2. Running both creates conflicts.

If you’re not using Docker Desktop and want to run the Docker daemon natively inside WSL2, you need a distro with systemd enabled (Ubuntu 22.04+ in WSL2 supports this). Edit /etc/wsl.conf:

[boot]
systemd=true

Restart WSL, then use sudo systemctl start docker as on a regular Linux system.

Fix 4: Check the DOCKER_HOST Environment Variable

The Docker CLI checks the DOCKER_HOST environment variable to determine where to connect. If this variable is set to a host that isn’t running a daemon, you get the connection error.

Check if it’s set:

echo $DOCKER_HOST

If it shows something like tcp://192.168.1.100:2375 or tcp://localhost:2375, the CLI is trying to connect to that address instead of the local Unix socket.

To reset it to the default (local socket):

unset DOCKER_HOST

Then test:

docker info

If that works, find where DOCKER_HOST is being set. Check your shell profile files:

grep -r "DOCKER_HOST" ~/.bashrc ~/.zshrc ~/.profile ~/.bash_profile 2>/dev/null

Remove or comment out the offending line to make the fix permanent.

If you intentionally use a remote Docker host, make sure the remote daemon is running and reachable. Test connectivity:

curl http://YOUR_REMOTE_HOST:2375/version

If you get a connection refused error, the remote daemon isn’t running or isn’t configured to accept TCP connections.

Fix 5: Check Docker Context Configuration

Docker contexts let you switch between multiple Docker endpoints. If the active context points to a non-existent or unreachable daemon, every command fails.

List your contexts:

docker context ls

The active context is marked with an asterisk (*). Check the endpoint it’s using:

NAME         DESCRIPTION                               DOCKER ENDPOINT
default *    Current DOCKER_HOST based configuration    unix:///var/run/docker.sock
remote       Production server                         tcp://prod.example.com:2376

If the wrong context is active, switch back to the default:

docker context use default

If you previously created a context that no longer exists or points to a decommissioned server, remove it:

docker context rm remote

Docker stores context configuration in ~/.docker/contexts/. If the configuration is corrupted, you can reset by removing the directory and recreating your contexts.

Fix 6: Fix Docker Socket Permissions

The daemon might be running, but your user can’t access the socket. Verify the socket exists:

ls -la /var/run/docker.sock

You should see something like:

srw-rw---- 1 root docker 0 Mar  9 10:00 /var/run/docker.sock

The socket is owned by root and the docker group. If your user isn’t in the docker group, you’ll get a permission error that can sometimes appear as a connection failure rather than a permission denied message.

Add your user to the docker group:

sudo usermod -aG docker $USER

Then log out and log back in for the group change to take effect. Or start a new shell with the updated groups:

newgrp docker

For a deeper dive into Docker socket permission problems, see Docker permission denied while trying to connect to the daemon socket.

Note: Adding your user to the docker group grants root-equivalent access to the system. On shared machines or production servers, consider rootless Docker instead.

Fix 7: Docker Desktop vs Docker Engine

Understanding the difference prevents a lot of confusion.

Docker Engine is the daemon (dockerd) plus the CLI. It runs natively on Linux. You install it via apt, dnf, pacman, or the official Docker repository. You manage it with systemctl.

Docker Desktop is a GUI application that runs Docker Engine inside a VM. It’s the standard install on macOS and Windows, and is also available on Linux. It bundles its own daemon, CLI, Docker Compose, and Kubernetes.

Problems arise when both are installed on the same Linux machine. You end up with two daemons, two sockets, and confusion about which one the CLI is talking to.

Check which Docker binary you’re using:

which docker
  • /usr/bin/docker usually comes from the Docker Engine package.
  • /usr/local/bin/docker or a path inside /opt/ might come from Docker Desktop.

If you have both installed, pick one and remove the other. Having both causes socket conflicts, context confusion, and subtle bugs.

To check if Docker Desktop is managing your daemon on Linux:

docker context ls

Docker Desktop typically creates a context called desktop-linux.

Fix 8: Snap vs Apt Installation Differences (Ubuntu)

On Ubuntu, Docker can be installed via:

  • Official Docker repository (apt) — the recommended method.
  • Ubuntu’s default repository (apt install docker.io).
  • Snap (snap install docker).

The snap installation is sandboxed and uses a different socket path. Instead of /var/run/docker.sock, snap Docker might use /var/snap/docker/current/run/docker.sock.

If you installed Docker via snap but your CLI expects the standard socket:

sudo snap start docker

Check the snap service status:

sudo snap services docker

To avoid these path issues, the Docker team recommends installing from their official apt repository. If you want to switch from snap to apt:

sudo snap remove docker

Then follow the official Docker installation guide to install via apt.

If you have both snap and apt versions installed, remove one. Check which is installed:

snap list docker 2>/dev/null && echo "Snap version installed"
dpkg -l docker-ce 2>/dev/null | grep -q "^ii" && echo "Apt version installed"

Fix 9: Start the Daemon Manually (Without systemd)

On systems without systemd (older distros, containers, minimal installs), you can start the daemon manually:

sudo dockerd &

This runs dockerd in the background. Check if it’s working:

docker info

For a more robust setup without systemd, use a process manager like supervisord or add a startup script to /etc/rc.local.

If dockerd fails to start, run it in the foreground to see the error output:

sudo dockerd

Common startup errors include:

  • Storage driver issues: The default storage driver (overlay2) requires a filesystem that supports it (ext4, xfs). If your filesystem doesn’t support it, configure a different driver in /etc/docker/daemon.json.
  • Port conflicts: Another process might be using a port Docker needs.
  • Corrupted state: Remove /var/lib/docker to reset (this deletes all containers, images, and volumes).

Fix 10: Set Up Rootless Docker

Rootless Docker runs the daemon as a non-root user. It avoids permission issues entirely and is more secure.

Install the prerequisites:

sudo apt install -y uidmap dbus-user-session

Run the rootless setup script:

dockerd-rootless-setuptool.sh install

This creates a user-level systemd service. Start it:

systemctl --user start docker

Enable it to start on login:

systemctl --user enable docker

Set the DOCKER_HOST variable to point to your rootless socket:

export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock

Add this line to your ~/.bashrc or ~/.zshrc to make it permanent.

Rootless Docker has some limitations. It can’t bind to ports below 1024 without extra configuration, and some storage drivers aren’t available. But for development and CI environments, it’s a solid choice.

Fix 11: Check if Docker Is Installed

This might seem obvious, but the error message is the same whether Docker isn’t running or isn’t installed at all. Verify:

docker --version

If the command isn’t found, Docker isn’t installed. On Ubuntu/Debian:

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

On Fedora/CentOS/RHEL:

sudo dnf install -y docker-ce docker-ce-cli containerd.io

Make sure you’ve added Docker’s official repository first. The packages in your distro’s default repository may be outdated or named differently (docker.io on Debian/Ubuntu).

Still Not Working?

If none of the fixes above resolved the error, try these less common solutions:

Check if containerd is running. Docker depends on containerd. If it crashed, Docker can’t start:

sudo systemctl status containerd
sudo systemctl start containerd

Check for conflicting container runtimes. If you have Podman installed alongside Docker, there can be conflicts with the /var/run/docker.sock path. Podman can create a Docker-compatible socket that interferes with the real Docker daemon.

Inspect /etc/docker/daemon.json for errors. A syntax error in this file prevents the daemon from starting. Validate the JSON:

python3 -m json.tool /etc/docker/daemon.json

If it shows a parse error, fix the JSON syntax and restart Docker.

Reinstall Docker completely. As a last resort, remove and reinstall:

sudo apt purge docker-ce docker-ce-cli containerd.io
sudo rm -rf /var/lib/docker /var/lib/containerd /etc/docker
sudo apt install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker

Warning: This deletes all Docker data, including images, containers, and volumes. Back up anything important first.

Check firewall rules. On systems with strict firewall configurations, iptables or nftables rules might block Docker’s internal communication. Docker modifies iptables rules during startup. If another tool resets those rules, Docker can break:

sudo iptables -L -n | grep -i docker

If there are no Docker-related rules and Docker was previously working, restart the daemon to let it recreate them.

If you’re running into memory-related crashes where the daemon starts but immediately dies, the system might be killing Docker due to OOM. Check dmesg for OOM killer messages:

dmesg | grep -i "oom\|killed"

Check for cgroup v2 incompatibility. Newer Linux distros (Ubuntu 22.04+, Fedora 31+, Debian 11+) default to cgroup v2. Older Docker versions (pre-20.10) do not support cgroup v2 and the daemon refuses to start. Either upgrade Docker or temporarily fall back to cgroup v1 by adding systemd.unified_cgroup_hierarchy=0 to your kernel command line. The fix in 2026 is almost always “upgrade Docker.”

Check iptables-nft vs iptables-legacy. Modern Debian and Ubuntu use nftables as the backend for iptables. Some Docker versions assume the legacy iptables binary. Run update-alternatives --config iptables and pick iptables-legacy if Docker logs complain about iptables: Failed to initialize nft. After switching, restart Docker.

Check for a stale ~/.docker/config.json with the wrong credsStore. If the file references a credential helper binary that is no longer installed (for example, docker-credential-desktop after uninstalling Docker Desktop), every CLI command can fail before it ever contacts the daemon. The error sometimes surfaces as a generic connection failure. Edit the file and remove or change the credsStore entry.

Check Colima or Rancher Desktop on macOS. If you installed Colima or Rancher Desktop alongside or instead of Docker Desktop, your docker CLI may be aimed at the wrong VM. Run docker context ls and switch with docker context use colima (or docker context use rancher-desktop) explicitly, then start the matching VM.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles