Docker Error Guide: 'Cannot connect to the Docker daemon at tcp://host:2375' Remote Failure
Fix Docker 'Cannot connect to the Docker daemon at tcp://host:2375' errors: check DOCKER_HOST, the daemon TCP listener, firewall reachability, and TLS on 2376 versus plain 2375.
- #docker
- #troubleshooting
- #errors
- #daemon
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Exact Error Message
Cannot connect to the Docker daemon at tcp://10.0.4.12:2375. Is the docker daemon running?
When TLS is misaligned you may see a variation that proves the port is open but the handshake is wrong:
error during connect: Get "https://10.0.4.12:2376/v1.45/containers/json":
http: server gave HTTP response to HTTPS client
Both point at the same class of problem: the client cannot establish a usable connection to a remote Docker daemon over TCP.
What It Means
By default the Docker client talks to the daemon over a local Unix socket (/var/run/docker.sock). When you set DOCKER_HOST=tcp://host:2375 (or -H), the client instead tries to reach the daemon over TCP. This error means that TCP connection did not succeed: either nothing is listening on that host and port, a firewall drops the packets, the daemon is not configured to expose a TCP listener, or the transport security does not match.
Two ports matter by convention. 2375 is the plaintext, unauthenticated Docker API port. 2376 is the TLS-protected port. Plaintext 2375 exposes full root-equivalent control of the host to anyone who can reach it, so it should never be open on an untrusted network.
Common Causes
DOCKER_HOSTis set to a remote TCP endpoint but the daemon only listens on the local Unix socket.- The daemon has no TCP listener configured in
/etc/docker/daemon.jsonor its systemd unit. - A firewall or security group blocks 2375/2376 between client and host.
- TLS mismatch: connecting with
https/certs to a plaintext port, or plaintext to a TLS port. - The remote Docker service is stopped or crashed.
- A stale
DOCKER_HOSTleft over in the shell from a previous context.
Diagnostic Commands
Check whether the client is even pointed at a remote host:
echo "$DOCKER_HOST"
docker context ls
From the client, test raw TCP reachability to the port:
nc -vz 10.0.4.12 2375
On the Docker host, confirm the daemon is running and what it is listening on:
systemctl status docker
ss -tlnp | grep -E '2375|2376'
Inspect the daemon’s configured hosts:
cat /etc/docker/daemon.json
Step-by-Step Resolution
- Confirm your intent. For local work, unset the remote endpoint so the client uses the Unix socket:
unset DOCKER_HOST
docker info
- If you genuinely want remote access, do it securely with TLS on 2376, not plaintext 2375. Configure the daemon host list. Edit
/etc/docker/daemon.json:
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
"tls": true,
"tlscacert": "/etc/docker/certs/ca.pem",
"tlscert": "/etc/docker/certs/server-cert.pem",
"tlskey": "/etc/docker/certs/server-key.pem",
"tlsverify": true
}
- If a systemd unit also sets
-H, remove the conflicting flag or it will clash withdaemon.json. Then reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart docker
- Open the port to trusted clients only in your firewall/security group. Never expose 2375 to the public internet:
sudo ufw allow from 10.0.4.0/24 to any port 2376 proto tcp
- Point the client at the TLS endpoint using a context, which is cleaner than juggling env vars:
docker context create remote \
--docker "host=tcp://10.0.4.12:2376,ca=~/.docker/ca.pem,cert=~/.docker/cert.pem,key=~/.docker/key.pem"
docker context use remote
- Verify end to end:
docker info
Server:
Containers: 4
Server Version: 26.1.0
Prevention
- Prefer Docker contexts or SSH (
tcp://overssh://user@host) instead of storing plaintextDOCKER_HOSTvalues. - Never expose 2375 (plaintext) on any network you do not fully trust; use 2376 with mutual TLS.
- Restrict the TCP port to specific source ranges at the firewall/security-group level.
- Keep the daemon’s
hostsin exactly one place,daemon.jsonor the systemd unit, never both. - Use
ssh://transport for ad-hoc remote access; it needs no open Docker port at all. For generating secure daemon and TLS setups, the DevOps AI prompt library has ready templates.
Related Errors
Cannot connect to the Docker daemon at unix:///var/run/docker.sock— the local-socket variant, usually a stopped daemon or permissions.http: server gave HTTP response to HTTPS client— TLS client hitting a plaintext port.x509: certificate signed by unknown authority— TLS is on but the CA does not match.dial tcp: connect: connection refused— nothing listening on the target port.
Frequently Asked Questions
What is the difference between ports 2375 and 2376? 2375 is the unencrypted, unauthenticated Docker API and grants root-equivalent control to anyone who can reach it. 2376 is the TLS-secured port with certificate authentication. Use 2376 for anything beyond an isolated lab.
Why does the daemon ignore my daemon.json hosts entry? Because a systemd unit is passing its own -H flag, which conflicts. Remove the -H from the unit’s ExecStart (or the hosts line from daemon.json) so only one source defines the listeners, then reload.
Should I ever open 2375 to the internet? No. Plaintext 2375 is effectively remote root with no authentication. Restrict it to a trusted subnet at minimum, and prefer TLS on 2376 or ssh:// transport.
Can I reach a remote daemon without opening any TCP port? Yes. Use DOCKER_HOST=ssh://user@host or a Docker context with ssh://, which tunnels the API over SSH and needs no exposed Docker port. For more, 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.