Docker Error Guide: 'Cannot connect to the Docker daemon' — Wrong Context Endpoint
Fix 'Cannot connect to the Docker daemon' caused by an active Docker context or DOCKER_HOST pointing at an unreachable endpoint: list, inspect, recreate, and switch back to default.
- #docker
- #troubleshooting
- #errors
- #context
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
Every docker command fails, even though the local daemon is running fine. The client is talking to the wrong endpoint because the active Docker context (or a DOCKER_HOST variable) points at a remote or misconfigured daemon:
Cannot connect to the Docker daemon at ssh://deploy@build-host:22. Is the docker daemon running?
The local socket variant is the same class of problem — the client resolved an endpoint it can’t reach:
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
The daemon may be perfectly healthy; the client is just pointed somewhere unreachable.
Symptoms
docker ps,docker build, etc. all fail withCannot connect to the Docker daemon at <endpoint>.- The endpoint in the error is a remote
ssh://ortcp://host, notunix:///var/run/docker.sock. sudo systemctl status dockershows the daemonactive (running)locally, yet the client can’t connect.- The problem followed you after using a remote context (
docker context use) or exportingDOCKER_HOST.
Common Root Causes
- Active context points at a down/unreachable remote — a previously created
ssh://ortcp://context whose host is offline, renamed, or firewalled. DOCKER_HOSToverrides the context — an exportedDOCKER_HOSTin your shell/profile silently wins overdocker context use.- Broken SSH remote context — the SSH key, user, or port changed, or the remote user isn’t in the
dockergroup. - Expired or wrong TLS material — a
tcp://…:2376context with stale/mismatched client certs. - Context left switched in CI — a pipeline set a remote context and never switched back to
default.
Diagnostic Workflow
See which context is active (the * marks it) and where each points:
docker context ls
NAME DESCRIPTION DOCKER ENDPOINT ...
default Current DOCKER_HOST based ... unix:///var/run/docker.sock
remote * deploy build host ssh://deploy@build-host:22
Inspect the active context’s endpoint in detail:
docker context inspect remote | jq '.[0].Endpoints.docker'
Check whether DOCKER_HOST is overriding everything — if set, it takes precedence over the selected context:
echo "$DOCKER_HOST"
env | grep -i docker
If DOCKER_HOST is set, unset it so the context selection is honored:
unset DOCKER_HOST
Confirm the local daemon is actually up (rules the daemon out as the cause):
sudo systemctl status docker --no-pager
Test the remote endpoint’s transport directly before blaming Docker:
ssh deploy@build-host -p 22 'docker version' # for an ssh:// context
Example Root Cause Analysis
A developer runs docker ps and gets Cannot connect to the Docker daemon at ssh://deploy@build-host:22. The local daemon is fine (systemctl status docker is active (running)).
docker context ls shows remote * is active, pointing at ssh://deploy@build-host:22. docker context inspect remote | jq '.[0].Endpoints.docker' confirms the SSH endpoint. Testing the transport with ssh deploy@build-host -p 22 'docker version' returns Connection refused — the build host was decommissioned last week.
The client was left on a dead remote context by an earlier deploy session. Switching back to the local daemon resolves it immediately:
docker context use default
docker context ls # * now on default -> unix:///var/run/docker.sock
docker ps # works
Had DOCKER_HOST also been exported, docker context use default would appear to do nothing — the env var wins — so unset DOCKER_HOST would be the real fix.
Prevention Best Practices
- After any remote work, switch back explicitly:
docker context use default. - Prefer
docker context useover exportingDOCKER_HOST; if you must set the env var, unset it when done so it doesn’t shadow contexts. - In CI, scope remote contexts to a single step and never leave the runner on a remote context.
- Name remote contexts clearly (e.g.
staging-ssh,prod-tls) so a stray active context is obvious indocker context ls. - Recreate broken remotes cleanly rather than editing them by hand:
docker context rm remote
docker context create remote --docker "host=ssh://deploy@build-host:22"
Quick Command Reference
# Which context is active and where it points
docker context ls
docker context inspect remote | jq '.[0].Endpoints.docker'
# Env override check (wins over context)
echo "$DOCKER_HOST"
unset DOCKER_HOST
# Switch back to the local daemon
docker context use default
# Confirm the local daemon is up
sudo systemctl status docker --no-pager
# Recreate a remote context
docker context create remote --docker "host=ssh://deploy@build-host:22"
# Test the SSH transport directly
ssh deploy@build-host -p 22 'docker version'
Conclusion
Cannot connect to the Docker daemon when the daemon is clearly running almost always means the client is aimed at the wrong endpoint — a leftover remote context or an exported DOCKER_HOST. Read docker context ls and docker context inspect, remember that DOCKER_HOST overrides context selection, verify the transport (SSH/TLS) on its own, and get back to local with docker context use default. For more daemon and tooling fixes, see the Docker guides.
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.