KhueApps
Home/DevOps/Fix 'Get https://registry-1.docker.io/v2/: TLS handshake timeout'

Fix 'Get https://registry-1.docker.io/v2/: TLS handshake timeout'

Last updated: October 07, 2025

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)

  1. Verify connectivity and DNS.
  2. Sync system time (TLS depends on accurate clocks).
  3. Bypass or correctly configure proxies for Docker Hub.
  4. Increase client timeouts to be generous on slow networks.
  5. Reduce MTU if you are on VPN/cloud networks.
  6. 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.io or dig +short registry-1.docker.io
    • Windows PowerShell: Resolve-DnsName registry-1.docker.io
  • 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 status then sudo 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
  • 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
  • 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=300
    • export 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.conf to 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

CheckCommand
DNSdig +short registry-1.docker.io
TCP/443 reachability`timeout 5 bash -c '</dev/tcp/registry-1.docker.io/443' && echo OK
TLS handshakeopenssl s_client -connect registry-1.docker.io:443 -servername registry-1.docker.io -brief </dev/null
Hub API responsecurl -I https://registry-1.docker.io/v2/
Time synctimedatectl 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_TIMEOUT increases 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.

Series: Docker

DevOps