{"record":{"id":"c594ea47f8023559","repo":"golang/go","slug":"tls-client-sent-an-unexpected-quic-transport-para","errorCode":null,"errorMessage":"tls: client sent an unexpected quic_transport_parameters extension","messagePattern":"tls: client sent an unexpected quic_transport_parameters extension","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_server_tls13.go","lineNumber":284,"sourceCode":"\n\tif c.quic != nil {\n\t\t// RFC 9001 Section 4.2: Clients MUST NOT offer TLS versions older than 1.3.\n\t\tfor _, v := range hs.clientHello.supportedVersions {\n\t\t\tif v < VersionTLS13 {\n\t\t\t\tc.sendAlert(alertProtocolVersion)\n\t\t\t\treturn errors.New(\"tls: client offered TLS version older than TLS 1.3\")\n\t\t\t}\n\t\t}\n\t\t// RFC 9001 Section 8.2.\n\t\tif hs.clientHello.quicTransportParameters == nil {\n\t\t\tc.sendAlert(alertMissingExtension)\n\t\t\treturn errors.New(\"tls: client did not send a quic_transport_parameters extension\")\n\t\t}\n\t\tc.quicSetTransportParameters(hs.clientHello.quicTransportParameters)\n\t} else {\n\t\tif hs.clientHello.quicTransportParameters != nil {\n\t\t\tc.sendAlert(alertUnsupportedExtension)\n\t\t\treturn errors.New(\"tls: client sent an unexpected quic_transport_parameters extension\")\n\t\t}\n\t}\n\n\tc.serverName = hs.clientHello.serverName\n\treturn nil\n}\n\nfunc (hs *serverHandshakeStateTLS13) checkForResumption() error {\n\tc := hs.c\n\n\tif c.config.SessionTicketsDisabled {\n\t\treturn nil\n\t}\n\n\tmodeOK := false\n\tfor _, mode := range hs.clientHello.pskModes {\n\t\tif mode == pskModeDHE {\n\t\t\tmodeOK = true","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_server_tls13.go#L266-L302","documentation":"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.","triggerScenarios":"A TCP TLS client includes quic_transport_parameters in its ClientHello while the server is operating in non-QUIC mode (c.quic == nil).","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Do not send quic_transport_parameters over TCP. Keep QUIC and TCP TLS configs separate.\ntcpCfg := &tls.Config{ /* no QUIC params */ }\nquicCfg := &tls.Config{ /* QUIC-enabled */ }","typeGuard":null,"tryCatchPattern":"if err := tlsConn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"unexpected quic_transport_parameters\") {\n        log.Printf(\"non-QUIC client sent QUIC extension from %v\", remote)\n    }\n    c.Close()\n    return\n}","preventionTips":["Use separate TLS configs for QUIC and TCP transports","Condition the quic_transport_parameters extension on the connection actually being QUIC"],"tags":["tls","go","quic","transport-parameters","handshake","config"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}