golang/go · error

tls: invalid server key share

Error message

tls: invalid server key share

What it means

During establishHandshakeKeys, Go computes the ECDH shared secret from the server's key share. If the crypto operation fails (the server's share is malformed, not on the curve, wrong length, or an invalid point), Go wraps it as 'tls: invalid server key share' and sends `illegal_parameter`. This guards against malformed or attack-crafted public keys.

Source

Thrown at src/crypto/tls/handshake_client_tls13.go:482

	c.peerCertificates = hs.session.peerCertificates
	c.verifiedChains = hs.session.verifiedChains
	c.ocspResponse = hs.session.ocspResponse
	c.scts = hs.session.scts
	return nil
}

func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
	c := hs.c

	ke, err := keyExchangeForCurveID(hs.serverHello.serverShare.group)
	if err != nil {
		c.sendAlert(alertInternalError)
		return err
	}
	sharedKey, err := ke.clientSharedSecret(hs.keyShareKeys, hs.serverHello.serverShare.data)
	if err != nil {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: invalid server key share")
	}
	c.curveID = hs.serverHello.serverShare.group

	earlySecret := hs.earlySecret
	if !hs.usingPSK {
		earlySecret = tls13.NewEarlySecret(hs.suite.hash.New, nil)
	}

	handshakeSecret := earlySecret.HandshakeSecret(sharedKey)

	clientSecret := handshakeSecret.ClientHandshakeTrafficSecret(hs.transcript)
	c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
	serverSecret := handshakeSecret.ServerHandshakeTrafficSecret(hs.transcript)
	if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret, false); err != nil {
		return err
	}

	if c.quic != nil {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Treat the server's key share as untrusted and abort; do not retry indefinitely against the same peer.
  2. Capture the ServerHello key_share bytes and validate the point on the expected curve.
  3. Test against a known-good peer to rule out local tampering.
  4. Report to the server operator if the bad share is confirmed server-origin.
Defensive patterns

Strategy: try-catch

Try / catch

// Invalid server key share can be a security probe; do not auto-retry indefinitely.
if err := conn.Handshake(); err != nil {
    if strings.Contains(err.Error(), "invalid server key share") {
        log.Printf("possible MITM or buggy peer %s: %v", addr, err)
    }
    return err
}

Prevention

When it happens

Trigger: ke.clientSharedSecret returns an error when processing hs.serverHello.serverShare.data against the client's key share keys. Common when the server share is truncated, off-curve, or all-zero.

Common situations: Server bug producing a malformed public key, an active MITM (e.g., invalid-curve attack), corrupted packets, or a misbehaving TLS proxy. Rare against healthy peers.

Understand the failure class

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/84d9d7f16b20ee33. Report an issue: GitHub.