Skip to content
Latchkey

kubectl "net/http: TLS handshake timeout" - Fix API Server TLS in CI

kubectl opened the TCP connection but the TLS handshake did not complete in time. The endpoint is reachable but slow or overloaded, or a proxy/load balancer is interfering with the handshake. It is often transient.

What this error means

kubectl fails with Unable to connect to the server: net/http: TLS handshake timeout. Unlike a flat i/o timeout, the TCP connection succeeded - the delay is in the TLS negotiation. A retry frequently works.

kubectl output
Unable to connect to the server: net/http: TLS handshake timeout

Common causes

Overloaded or cold API endpoint

A control plane under load, or a load balancer with cold/unhealthy targets, completes the TCP connect but stalls the TLS handshake until it times out.

Proxy or MITM interfering

A corporate proxy, HTTPS_PROXY misconfiguration, or a TLS-inspecting middlebox between the runner and the API server disrupts the handshake.

How to fix it

Retry with backoff

Because the handshake stall is usually transient, a bounded retry clears most occurrences.

Terminal
for i in 1 2 3; do
  kubectl version --request-timeout=30s && break
  sleep $((i*5))
done

Rule out a proxy and check endpoint health

  1. Check HTTPS_PROXY/NO_PROXY - the API host may need to bypass a TLS-inspecting proxy.
  2. Confirm the API load balancer targets are healthy (control plane not overloaded).
  3. Test the handshake directly: openssl s_client -connect <api-host>:443.

How to prevent it

  • Add NO_PROXY entries so the API host bypasses TLS-inspecting proxies.
  • Wrap initial cluster calls in a bounded retry.
  • Keep the control plane appropriately sized so handshakes are not starved under load.

Frequently asked questions

What causes ""TLS handshake timeout""?
A control plane under load, or a load balancer with cold/unhealthy targets, completes the TCP connect but stalls the TLS handshake until it times out.
How do I fix "TLS handshake timeout"?
Because the handshake stall is usually transient, a bounded retry clears most occurrences.
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

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card