Skip to content
Latchkey

Docker "net/http: request canceled (Client.Timeout exceeded)" on Pull/Push

Docker’s HTTP client gave up waiting for the registry. The connection or response exceeded the client timeout - a transient network, DNS, or proxy slowdown between the runner and the registry.

What this error means

A docker pull/push fails with net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers). It is intermittent - re-running the job often succeeds with no change.

docker pull/push output
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http:
request canceled while waiting for connection (Client.Timeout exceeded while
awaiting headers)

Diagnose it: separate auth from naming from rate limits

Registry errors look alike and have unrelated causes. Work out which of the three you have before changing credentials, because a malformed image reference produces an error that reads like an authentication failure.

Terminal
# 1. is the reference even valid? (lowercase, no spaces, valid tag)
docker image inspect "$IMAGE" 2>&1 | head -2

# 2. are you authenticated to the right registry?
cat ~/.docker/config.json | grep -o '"[^"]*\.[^"]*"' | head

# 3. are you rate limited? (Docker Hub anonymous pulls)
curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimit-preview/test:pull" \
  | grep -o '"token"' >/dev/null && echo "token ok"

Common causes

Transient network or registry slowness

A brief connectivity blip, an overloaded registry edge, or a congested runner network makes the request exceed Docker’s client timeout. Nothing about your image is wrong.

DNS resolution stalling

Slow or failing DNS for the registry host delays the connection past the timeout, especially on runners with a flaky resolver.

A proxy/firewall silently dropping the connection

An HTTP(S) proxy or firewall that blackholes the registry connection causes the client to wait until it times out.

How to fix it

Retry with backoff

Because the failure is transient, a bounded retry usually succeeds without other changes.

Terminal
for i in 1 2 3; do
  docker pull myorg/api:1.4.2 && break
  echo "pull timed out (attempt $i), retrying..."; sleep $((i*10))
done

Fix DNS and proxy reachability

  1. Confirm the registry host resolves (getent hosts registry-1.docker.io).
  2. Set HTTP_PROXY/HTTPS_PROXY/NO_PROXY correctly for the daemon if a proxy is required.
  3. Use a closer mirror or pull-through cache to reduce round-trip time.

Authenticate in the job, not in the image

.github/workflows/ci.yml
- uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

# GHCR needs this on the job or the push is rejected as unauthorised
permissions:
  contents: read
  packages: write

How to prevent it

  • Wrap pulls/pushes in a bounded retry with backoff.
  • Ensure reliable DNS and correct proxy settings on runners.
  • Mirror or cache base images to cut dependence on a slow public registry.

Frequently asked questions

What causes Docker "net/http: request canceled (Client.Timeout exceeded)" on Pull/Push?
There are 3 common causes: transient network or registry slowness, dns resolution stalling, and a proxy/firewall silently dropping the connection. A brief connectivity blip, an overloaded registry edge, or a congested runner network makes the request exceed Docker’s client timeout.
How do I fix Docker "net/http: request canceled (Client.Timeout exceeded)" on Pull/Push?
There are 2 fixes depending on which cause you have: retry with backoff and fix dns and proxy reachability. Work through them in order, since the first is the most common.
What does Docker "net/http: request canceled (Client.Timeout exceeded)" on Pull/Push actually mean?
A docker pull/push fails with net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
How do I stop Docker "net/http: request canceled (Client.Timeout exceeded)" on Pull/Push happening again?
Wrap pulls/pushes in a bounded retry with backoff. The prevention section lists 3 changes that keep it from recurring.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

This is a transient network failure, not a bug in your code. Latchkey detects, repairs, and retries it for you. Start free → 30-day trial · No credit card