valyala/fasthttp · error

fasthttp: tls handshake timed out

Error message

fasthttp: tls handshake timed out

What it means

ErrTLSHandshakeTimeout indicates the TLS handshake with the remote host exceeded its deadline (Client.TLSHandshakeTimeout). fasthttp aborts the connection rather than waiting indefinitely on a stalled handshake.

Source

Thrown at client.go:2295

		c.tlsConfigMap = make(map[string]*tls.Config)
	}
	cfg := c.tlsConfigMap[addr]
	if cfg == nil {
		var err error
		cfg, err = newClientTLSConfig(c.TLSConfig, addr)
		if err != nil {
			c.tlsConfigMapLock.Unlock()
			return nil, err
		}
		c.tlsConfigMap[addr] = cfg
	}
	c.tlsConfigMapLock.Unlock()

	return cfg, nil
}

// ErrTLSHandshakeTimeout indicates there is a timeout from tls handshake.
var ErrTLSHandshakeTimeout = errors.New("fasthttp: tls handshake timed out")

func tlsClientHandshake(rawConn net.Conn, tlsConfig *tls.Config, deadline time.Time) (_ net.Conn, retErr error) {
	defer func() {
		if retErr != nil {
			rawConn.Close()
		}
	}()
	conn := tls.Client(rawConn, tlsConfig)
	err := conn.SetDeadline(deadline)
	if err != nil {
		return nil, err
	}
	err = conn.Handshake()
	if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
		return nil, ErrTLSHandshakeTimeout
	}
	if err != nil {
		return nil, err

View on GitHub (pinned to c96f600972)

Solutions

  1. Increase Client.TLSHandshakeTimeout to fit your network latency
  2. Check the network path and server TLS termination health
  3. Retry with backoff on ErrTLSHandshakeTimeout via Client.RetryIf or caller-side retry
  4. Reduce load on the TLS terminator or move to a faster endpoint/CDN

Example fix

// before
c := &fasthttp.Client{TLSHandshakeTimeout: 100 * time.Millisecond} // too tight for WAN
// after
c := &fasthttp.Client{TLSHandshakeTimeout: 10 * time.Second}
Defensive patterns

Strategy: retry

Validate before calling

if client.TLSHandshakeTimeout < 5*time.Second {
    client.TLSHandshakeTimeout = 10 * time.Second
}

Try / catch

if errors.Is(err, fasthttp.ErrTLSHandshakeTimeout) {
    time.Sleep(backoff)
    return do(req, resp) // bounded retry
}

Prevention

When it happens

Trigger: TLS requests where the server accepts the TCP connection but the handshake does not complete within TLSHandshakeTimeout; very slow networks or overloaded TLS terminators.

Common situations: Targets behind saturated load balancers; high-latency links with a very small TLSHandshakeTimeout; blackholed network paths where TCP connects but TLS stalls.

Understand the failure class

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/694e1155ee088013. Report an issue: GitHub.