Table of Contents
- Overview
- Quickstart (most common fixes)
- Minimal working example
- Step-by-step fixes
- 1) Confirm DNS and TLS path
- 2) Sync system time
- 3) Remove proxy interference or configure NO_PROXY
- 4) Increase Docker client timeouts (slow networks)
- 5) Add a registry mirror (faster pulls)
- 6) Fix MTU issues (common with VPNs)
- 7) Prefer IPv4 if IPv6 path is broken
- 8) Update CA certificates (trust store)
- 9) Restart Docker and retry
- Diagnostics you can run quickly
- Pitfalls
- Performance notes
- Tiny FAQ
Overview
This guide fixes the Docker error:
Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
It occurs when the Docker client cannot complete the TLS handshake with Docker Hub (registry-1.docker.io). Common causes: network or proxy issues, DNS resolution, MTU mismatches, clock skew, or slow links.
Quickstart (most common fixes)
- Verify connectivity and DNS.
- Sync system time (TLS depends on accurate clocks).
- Bypass or correctly configure proxies for Docker Hub.
- Increase client timeouts to be generous on slow networks.
- Reduce MTU if you are on VPN/cloud networks.
- Restart Docker and retry the pull.
Minimal working example
The snippet below performs basic checks, applies safe timeouts, and attempts a pull.
#!/usr/bin/env bash
set -euo pipefail
# 1) Connectivity and DNS
ping -c1 8.8.8.8 >/dev/null && echo "OK: network reachability" || echo "WARN: no ICMP reachability"
getent hosts registry-1.docker.io || true
# 2) TLS reachability to Docker Hub
openssl s_client -connect registry-1.docker.io:443 -servername registry-1.docker.io -brief </dev/null | sed -n '1,5p' || true
# 3) Increase client timeouts (no daemon restart needed)
export DOCKER_CLIENT_TIMEOUT=300
export COMPOSE_HTTP_TIMEOUT=300
# 4) Try a simple pull
docker pull hello-world
If it still times out, proceed with the steps below.
Step-by-step fixes
1) Confirm DNS and TLS path
- Check DNS resolution:
- Linux/macOS:
getent hosts registry-1.docker.ioordig +short registry-1.docker.io - Windows PowerShell:
Resolve-DnsName registry-1.docker.io
- Linux/macOS:
- Test TLS handshake:
openssl s_client -connect registry-1.docker.io:443 -servername registry-1.docker.io -brief </dev/null - If DNS fails or TLS cannot connect, investigate network/firewall first.
2) Sync system time
TLS verification can fail or stall when the clock is skewed.
- Linux:
timedatectl statusthensudo timedatectl set-ntp true - macOS: System Settings > Date & Time > Set time automatically
- Windows: Settings > Time & language > Date & time > Sync now
3) Remove proxy interference or configure NO_PROXY
TLS inspection or misconfigured proxies often cause handshake timeouts.
- Temporarily bypass proxy for a test:
- Linux/macOS:
env -u HTTP_PROXY -u HTTPS_PROXY docker pull hello-world - Alternatively:
NO_PROXY="*" docker pull hello-world
- Linux/macOS:
- If you must use a proxy, ensure Docker bypasses Hub endpoints:
- Add to NO_PROXY:
docker.io,registry-1.docker.io,auth.docker.io,localhost,127.0.0.1,::1
- Add to NO_PROXY:
- Docker Desktop: set proxy and NO_PROXY in Settings > Resources > Proxies.
4) Increase Docker client timeouts (slow networks)
- One-off in shell:
export DOCKER_CLIENT_TIMEOUT=300export COMPOSE_HTTP_TIMEOUT=300
- These do not fix broken networks but prevent premature timeouts on high-latency links.
5) Add a registry mirror (faster pulls)
Mirrors reduce latency and load on Docker Hub.
- Linux daemon configuration at
/etc/docker/daemon.json:
{
"registry-mirrors": ["https://mirror.gcr.io"],
"features": {"buildkit": true}
}
Then restart Docker: sudo systemctl restart docker (Linux) or restart Docker Desktop. Note: Authentication flow still contacts Docker Hub’s token service, but layers often come from the mirror.
6) Fix MTU issues (common with VPNs)
If small pings work but TLS stalls, reduce MTU for Docker networks.
- In
/etc/docker/daemon.json:
{
"mtu": 1400
}
Restart Docker, then recreate networks or restart containers. For custom networks: docker network create --opt com.docker.network.driver.mtu=1400 net1400.
7) Prefer IPv4 if IPv6 path is broken
Some environments have partial IPv6 that breaks TLS.
- System-wide (Linux): adjust
/etc/gai.confto prefer IPv4, then retry. Alternatively disable IPv6 if your network does not support it. - Docker IPv6 networks can be disabled via daemon settings:
{ "ipv6": false }(affects containers, not host DNS).
8) Update CA certificates (trust store)
Outdated trust stores can cause TLS issues.
- Debian/Ubuntu:
sudo apt-get update && sudo apt-get install -y ca-certificates && sudo update-ca-certificates - RHEL/CentOS:
sudo update-ca-trust - macOS/Windows: ensure system root certificates are current.
9) Restart Docker and retry
- Linux:
sudo systemctl daemon-reload && sudo systemctl restart docker - Docker Desktop: Quit and relaunch.
- Retry:
docker pull hello-world
Diagnostics you can run quickly
| Check | Command |
|---|---|
| DNS | dig +short registry-1.docker.io |
| TCP/443 reachability | `timeout 5 bash -c '</dev/tcp/registry-1.docker.io/443' && echo OK |
| TLS handshake | openssl s_client -connect registry-1.docker.io:443 -servername registry-1.docker.io -brief </dev/null |
| Hub API response | curl -I https://registry-1.docker.io/v2/ |
| Time sync | timedatectl status |
Healthy results: DNS returns addresses, TCP connect OK, TLS shows a selected ciphersuite, and curl -I returns HTTP 200 or 401 with Docker-Distribution-Api-Version header.
Pitfalls
- Setting "dns" in daemon.json affects containers, not the Docker client’s own DNS; the client uses the host resolver.
DOCKER_CLIENT_TIMEOUTincreases wait time but does not fix broken routing or proxies.- Registry mirrors do not bypass the token exchange; ensure your proxy/NO_PROXY allows access to
auth.docker.io. - Changing MTU requires recreating networks or a Docker restart.
Performance notes
- Use a nearby mirror (e.g.,
https://mirror.gcr.io) to reduce latency and pull time. - Keep a local registry cache for frequently used base images in CI.
- Enable BuildKit to reduce network usage via layer deduplication and concurrent fetching:
export DOCKER_BUILDKIT=1. - Stable DNS (multiple resolvers) speeds up name resolution under packet loss.
Tiny FAQ
- Does this mean Docker Hub is down?
- Usually no. It’s typically a local network, proxy, DNS, or MTU problem.
- Why does
curl https://registry-1.docker.io/v2/sometimes show 401?- That is normal for the API root. The key is that TLS completes and you get headers.
- Will increasing timeouts alone solve it?
- Only if the network is slow. If TLS handshake can’t complete due to filtering or MTU, fix those first.
- Do I need to log in?
- Not for public images like
hello-world, but logging in can reduce rate limits and sometimes changes the path through CDNs.
- Not for public images like