golang/go · error
tls: server did not send a key share
Error message
tls: server did not send a key share
What it means
processServerHello requires the ServerHello to contain a server key share. If serverShare.group == 0, the key_share extension is missing or empty, so Go sends `illegal_parameter`. A TLS 1.3 ServerHello without a key share is non-conformant.
Source
Thrown at src/crypto/tls/handshake_client_tls13.go:432
if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
c.sendAlert(alertUnexpectedMessage)
return errors.New("tls: server sent two HelloRetryRequest messages")
}
if len(hs.serverHello.cookie) != 0 {
c.sendAlert(alertUnsupportedExtension)
return errors.New("tls: server sent a cookie in a normal ServerHello")
}
if hs.serverHello.selectedGroup != 0 {
c.sendAlert(alertDecodeError)
return errors.New("tls: malformed key_share extension")
}
if hs.serverHello.serverShare.group == 0 {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: server did not send a key share")
}
if !slices.ContainsFunc(hs.hello.keyShares, func(ks keyShare) bool {
return ks.group == hs.serverHello.serverShare.group
}) {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: server selected unsupported group")
}
if !hs.serverHello.selectedIdentityPresent {
return nil
}
if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: server selected an invalid PSK")
}
if len(hs.hello.pskIdentities) != 1 || hs.session == nil {View on GitHub (pinned to b6b368adc5)
Solutions
- Confirm the server actually speaks TLS 1.3 and is not silently downgrading to 1.2.
- Capture the handshake and verify key_share is present in the ServerHello bytes.
- Check for TLS-terminating proxies that rewrite or drop extensions.
- Report to the server operator — TLS 1.3 ServerHello must include a key_share.
Defensive patterns
Strategy: try-catch
Try / catch
conn, err := tls.Dial("tcp", addr, cfg)
if err != nil {
if strings.Contains(err.Error(), "did not send a key share") {
// possibly a server that downgraded to TLS 1.2 silently or a stripping proxy
log.Printf("peer %s omitted ServerHello key_share", addr)
}
return err
} Prevention
- Set Config.MinVersion = tls.VersionTLS13 so silent TLS 1.2 downgrades are rejected explicitly rather than masquerading as 1.3 faults.
- Audit the network path for proxies that strip extensions.
- Validate the server's TLS 1.3 support with a reference client (openssl s_client).
When it happens
Trigger: ServerHello.keyShare/serverShare parsed with group 0 — either the extension was absent or it was empty. Reached for any TLS 1.3 ServerHello missing the key_share extension.
Common situations: Server that negotiated TLS 1.3 but failed to send key_share (e.g., misrouted PSK-only handshake, server bug), a downgrade-attack scenario, or a faulty proxy stripping extensions.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: malformed key_share extension
- tls: invalid server 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/94be89deca4ac68a.
Report an issue: GitHub.