golang/go · error
tls: client sent an unexpected quic_transport_parameters ext
Error message
tls: client sent an unexpected quic_transport_parameters extension
What it means
The quic_transport_parameters extension is QUIC-only (RFC 9001). In a non-QUIC (TCP) TLS handshake, its presence is unexpected and the server sends unsupported_extension.
Source
Thrown at src/crypto/tls/handshake_server_tls13.go:284
if c.quic != nil {
// RFC 9001 Section 4.2: Clients MUST NOT offer TLS versions older than 1.3.
for _, v := range hs.clientHello.supportedVersions {
if v < VersionTLS13 {
c.sendAlert(alertProtocolVersion)
return errors.New("tls: client offered TLS version older than TLS 1.3")
}
}
// RFC 9001 Section 8.2.
if hs.clientHello.quicTransportParameters == nil {
c.sendAlert(alertMissingExtension)
return errors.New("tls: client did not send a quic_transport_parameters extension")
}
c.quicSetTransportParameters(hs.clientHello.quicTransportParameters)
} else {
if hs.clientHello.quicTransportParameters != nil {
c.sendAlert(alertUnsupportedExtension)
return errors.New("tls: client sent an unexpected quic_transport_parameters extension")
}
}
c.serverName = hs.clientHello.serverName
return nil
}
func (hs *serverHandshakeStateTLS13) checkForResumption() error {
c := hs.c
if c.config.SessionTicketsDisabled {
return nil
}
modeOK := false
for _, mode := range hs.clientHello.pskModes {
if mode == pskModeDHE {
modeOK = trueView on GitHub (pinned to b6b368adc5)
Solutions
- Do not send quic_transport_parameters in non-QUIC (TCP) TLS handshakes
- Use separate TLS configurations/transports for QUIC vs TCP
- Condition the extension on the connection being QUIC
Defensive patterns
Strategy: validation
Validate before calling
// Do not send quic_transport_parameters over TCP. Keep QUIC and TCP TLS configs separate.
tcpCfg := &tls.Config{ /* no QUIC params */ }
quicCfg := &tls.Config{ /* QUIC-enabled */ } Try / catch
if err := tlsConn.Handshake(); err != nil {
if strings.Contains(err.Error(), "unexpected quic_transport_parameters") {
log.Printf("non-QUIC client sent QUIC extension from %v", remote)
}
c.Close()
return
} Prevention
- Use separate TLS configs for QUIC and TCP transports
- Condition the quic_transport_parameters extension on the connection actually being QUIC
When it happens
Trigger: A TCP TLS client includes quic_transport_parameters in its ClientHello while the server is operating in non-QUIC mode (c.quic == nil).
Common situations: A QUIC-aware client mistakenly used over TCP; a TLS config object reused across QUIC and TCP transports; a client library that always adds the extension.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: client did not send a quic_transport_parameters extensi
- tls: client offered TLS version older than TLS 1.3
- tls: missing signature_algorithms from TLS 1.2 peer
- tls: peer doesn't support any of the certificate's signature
- tls: server chose an unconfigured cipher suite
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/c594ea47f8023559.
Report an issue: GitHub.