Docker Error Guide: 'net/http: request canceled while waiting for connection' — Registry Timeouts
Fix Docker's 'net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)' caused by proxy, DNS, or registry timeouts.
- #docker
- #troubleshooting
- #errors
- #networking
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
This error is Docker’s HTTP client giving up on a registry request that never completed in time. It surfaces during docker pull, docker push, or docker login:
net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
The full context usually names the registry the daemon could not reach:
Error response from daemon: Get "https://registry.example.com/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
It is a networking timeout, not an authentication or image problem. The Docker daemon opened (or tried to open) a connection to the registry and no response headers arrived before the client deadline.
Symptoms
docker pullordocker pushhangs for several seconds, then fails withClient.Timeout exceeded while awaiting headers.docker login registry.example.comtimes out before prompting for or accepting credentials.- Pulls from Docker Hub work but a private registry (or vice versa) times out.
- The failure is intermittent — retries sometimes succeed — pointing at flaky networking rather than a hard misconfiguration.
curlto the same registry endpoint from the host also hangs or is slow.
Common Root Causes
- Corporate HTTP/HTTPS proxy not configured for the daemon — the shell has
HTTP_PROXYset but the Docker daemon does not, so it tries a direct route that a firewall drops. - DNS resolution failures or slowness — the daemon cannot resolve the registry hostname quickly.
- Firewall or egress rules blocking outbound 443 to the registry.
- Registry overloaded or down — the server accepts the TCP connection but never returns headers.
- MTU / VPN issues — packets to the registry are silently dropped after the TLS handshake.
- Wrong or stale proxy pointing at a proxy host that no longer accepts connections.
- IPv6 preference where the host advertises AAAA records but has no working IPv6 route.
Diagnostic Workflow
First reproduce and read the daemon’s own logs while pulling:
docker pull registry.example.com/myapp:1.4.2
sudo journalctl -u docker --since '5 minutes ago' | grep -i 'timeout\|canceled\|proxy'
Test raw connectivity and DNS independently of Docker:
getent hosts registry.example.com
curl -v --max-time 15 https://registry.example.com/v2/
If curl succeeds but Docker fails, the daemon has different network settings than your shell — almost always a missing proxy. Check the daemon’s effective proxy environment:
sudo systemctl show docker --property=Environment
docker info | grep -i proxy
Confirm what the shell sees for comparison:
env | grep -i proxy
If DNS is suspect, test resolution from the host and try a known-good resolver:
nslookup registry.example.com
dig +short registry.example.com
Example Root Cause Analysis
A CI runner behind a corporate proxy pulls fine when an engineer runs curl but docker pull registry.example.com/myapp:1.4.2 fails with Client.Timeout exceeded while awaiting headers. Comparing environments reveals the cause:
env | grep -i proxy
# HTTP_PROXY=http://proxy.example.com:3128
# HTTPS_PROXY=http://proxy.example.com:3128
docker info | grep -i proxy
# (no proxy configured)
The shell has proxy variables but the Docker daemon does not, so the daemon attempts a direct connection that the egress firewall drops — no headers ever return. The fix is to give the daemon its own proxy configuration via a systemd drop-in:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf >/dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=http://proxy.example.com:3128"
Environment="NO_PROXY=localhost,127.0.0.1,.internal.example.com"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
After restarting, docker info shows the proxy and the pull completes because the daemon now routes registry traffic through the approved egress path.
Prevention Best Practices
- Configure proxy settings for the Docker daemon (systemd drop-in) and the client, not just the shell, on every host behind a proxy.
- Add internal registries and cluster domains to
NO_PROXYso local traffic bypasses the proxy. - Monitor registry reachability with a lightweight
curl https://registry/v2/health check and alert on latency. - Pin reliable DNS resolvers and verify resolution of every registry hostname during host provisioning.
- Use a pull-through registry mirror to reduce dependence on a single upstream and smooth out transient outages.
- Keep VPN/MTU settings consistent; clamp MSS if large TLS responses hang after the handshake.
Quick Command Reference
# Read daemon logs during a failed pull
sudo journalctl -u docker --since '5 minutes ago' | grep -i 'timeout\|proxy'
# Test registry reachability outside Docker
curl -v --max-time 15 https://registry.example.com/v2/
# Compare shell vs daemon proxy config
env | grep -i proxy
docker info | grep -i proxy
# DNS checks
dig +short registry.example.com
# Restart after editing the systemd proxy drop-in
sudo systemctl daemon-reload && sudo systemctl restart docker
Conclusion
net/http: request canceled while waiting for connection means the Docker daemon started a registry request and no response headers arrived before the timeout — a networking problem, not an image or auth failure. Diagnose it by testing connectivity outside Docker, comparing the daemon’s proxy and DNS settings against a working curl, and reading journalctl -u docker. The most common fix is configuring a proxy for the daemon itself via a systemd drop-in. For more registry and networking 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.