The TCP connection opened but the TLS handshake did not finish in time. In CI this is almost always a transient network stall to a registry or API, not a certificate problem.
What this error means
A pull, push, or HTTPS request fails with net/http: TLS handshake timeout. Re-running the same job usually succeeds, indicating a transient blip.
shell
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: TLS handshake timeout
Common causes
Transient network stall during the handshake
Packet loss or congestion stops the TLS exchange from completing within the client timeout.
An overloaded or rate-limited endpoint
A registry under load may accept the TCP connection but lag on the handshake.
How to fix it
Retry the secure request
Bounded retries cover a transient handshake stall.
shell
for i in 1 2 3; do
docker pull alpine:3 && break
sleep $((i*10))
done
Reduce load on the endpoint
Authenticate to registries to lift anonymous rate limits.
Use a pull-through cache/mirror to cut direct hits.
Pin and cache images to reduce handshakes.
How to prevent it
Retry registry/HTTPS calls in CI.
Authenticate to avoid anonymous throttling.
On managed runners, transient TLS-handshake timeouts are detected and the job is automatically retried, so a one-off blip does not fail the build.
Frequently asked questions
What causes "TLS handshake timeout"?
Packet loss or congestion stops the TLS exchange from completing within the client timeout.
How do I fix TLS handshake timeout?
Bounded retries cover a transient handshake stall.
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.