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
- Treat the server's key share as untrusted and abort; do not retry indefinitely against the same peer.
- Capture the ServerHello key_share bytes and validate the point on the expected curve.
- Test against a known-good peer to rule out local tampering.
- 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
- Treat invalid-curve / malformed key-share errors as security-relevant; investigate before retrying.
- Use certificate pinning or VerifyConnection callbacks to add defence in depth against MITM.
- Prefer X25519 (which has built-in cofactor handling) to reduce off-curve attack surface.
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: malformed key_share extension
- tls: server did not send a key share
- tls: server sent two HelloRetryRequest messages
- tls: server sent a cookie in a normal ServerHello
- tls: server selected an invalid PSK
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/84d9d7f16b20ee33.
Report an issue: GitHub.