Skip to content
DevOps AI ToolKit
Newsletter
All guides
Docker with AI By James Joyner IV · · 9 min read

Docker Error Guide: 'Cannot connect to the Docker daemon at tcp://host:2375' Remote Failure

Quick answer

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.

Part of the Docker Container & Runtime Errors hub
  • #docker
  • #troubleshooting
  • #errors
  • #daemon
Free toolkit

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_HOST is 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.json or 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_HOST left 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

  1. Confirm your intent. For local work, unset the remote endpoint so the client uses the Unix socket:
unset DOCKER_HOST
docker info
  1. 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
}
  1. If a systemd unit also sets -H, remove the conflicting flag or it will clash with daemon.json. Then reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart docker
  1. 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
  1. 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
  1. Verify end to end:
docker info
Server:
 Containers: 4
 Server Version: 26.1.0

Prevention

  • Prefer Docker contexts or SSH (tcp:// over ssh://user@host) instead of storing plaintext DOCKER_HOST values.
  • 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 hosts in exactly one place, daemon.json or 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.
  • 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.

Free download · 368-page PDF

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.