golang/go · error
tls: malformed key_share extension
Error message
tls: malformed key_share extension
What it means
In a normal ServerHello, the key_share extension carries the server's share but must NOT also include the selectedGroup field (that field is HRR-only per RFC 8446 §4.2.8). Go treats a non-zero selectedGroup here as a malformed message and sends `decode_error`. The server is encoding the extension incorrectly.
Source
Thrown at src/crypto/tls/handshake_client_tls13.go:427
return nil
}
func (hs *clientHandshakeStateTLS13) processServerHello() error {
c := hs.c
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) {View on GitHub (pinned to b6b368adc5)
Solutions
- Report the malformed extension to the server operator.
- Verify with a packet capture which side injects selectedGroup into the ServerHello.
- Test against a reference Go tls.Server peer to localise the fault.
- Patch the server's key_share encoder to use the ServerHello shape (server_share only).
Defensive patterns
Strategy: try-catch
Try / catch
if err := conn.Handshake(); err != nil {
if strings.Contains(err.Error(), "malformed key_share extension") {
log.Printf("peer sent selected_group in a non-HRR ServerHello: %v", err)
}
return err
} Prevention
- Treat malformed-extension errors as fatal for the peer; investigate before reconnecting.
- Packet-capture handshakes when these errors appear to confirm the source.
- Reject middleboxes that rewrite key_share.
When it happens
Trigger: ServerHello.selectedGroup != 0 in processServerHello. Means the server put the HRR-shaped key_share (with selected_group) into a normal ServerHello.
Common situations: Hand-rolled or buggy TLS 1.3 server, fuzz traffic, or a middlebox that rewrites the key_share extension. Stock compliant servers never produce this.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- tls: server did not send a key share
- 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/3ae1f5edceb4961c.
Report an issue: GitHub.