{"record":{"id":"00bfcc27573b2e69","repo":"golang/go","slug":"tls-server-did-not-send-a-quic-transport-paramete","errorCode":null,"errorMessage":"tls: server did not send a quic_transport_parameters extension","messagePattern":"tls: server did not send a quic_transport_parameters extension","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client_tls13.go","lineNumber":551,"sourceCode":"\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(encryptedExtensions, msg)\n\t}\n\n\tif err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol, c.quic != nil); err != nil {\n\t\t// RFC 8446 specifies that no_application_protocol is sent by servers, but\n\t\t// does not specify how clients handle the selection of an incompatible protocol.\n\t\t// RFC 9001 Section 8.1 specifies that QUIC clients send no_application_protocol\n\t\t// in this case. Always sending no_application_protocol seems reasonable.\n\t\tc.sendAlert(alertNoApplicationProtocol)\n\t\treturn err\n\t}\n\tc.clientProtocol = encryptedExtensions.alpnProtocol\n\n\tif c.quic != nil {\n\t\tif encryptedExtensions.quicTransportParameters == nil {\n\t\t\t// RFC 9001 Section 8.2.\n\t\t\tc.sendAlert(alertMissingExtension)\n\t\t\treturn errors.New(\"tls: server did not send a quic_transport_parameters extension\")\n\t\t}\n\t\tc.quicSetTransportParameters(encryptedExtensions.quicTransportParameters)\n\t} else {\n\t\tif encryptedExtensions.quicTransportParameters != nil {\n\t\t\tc.sendAlert(alertUnsupportedExtension)\n\t\t\treturn errors.New(\"tls: server sent an unexpected quic_transport_parameters extension\")\n\t\t}\n\t}\n\n\tif !hs.hello.earlyData && encryptedExtensions.earlyData {\n\t\tc.sendAlert(alertUnsupportedExtension)\n\t\treturn errors.New(\"tls: server sent an unexpected early_data extension\")\n\t}\n\tif hs.hello.earlyData && !encryptedExtensions.earlyData {\n\t\tc.quicRejectedEarlyData()\n\t}\n\tif encryptedExtensions.earlyData {\n\t\tif hs.session.cipherSuite != c.cipherSuite {","sourceCodeStart":533,"sourceCodeEnd":569,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client_tls13.go#L533-L569","documentation":"QUIC-specific: RFC 9001 §8.2 mandates that a QUIC server's EncryptedExtensions carry the quic_transport_parameters extension. When the tls.Config is in QUIC mode (c.quic != nil) and the extension is absent, Go sends `missing_extension` and aborts. Indicates a QUIC server that did not echo transport parameters.","triggerScenarios":"Calling tls.Config for a QUIC connection (config has QUIC transport parameters set via QUIC control-plane APIs) and the server's EncryptedExtensions omits quic_transport_parameters.","commonSituations":"QUIC server (HTTP/3, QUIC transport) that does not implement the TLS-QUIC integration correctly, version skew between the QUIC library and the server, or a server that is actually a plain TLS server reached over a QUIC tunnel.","solutions":["Confirm the peer is actually a QUIC server, not a plain TLS-over-TCP server.","Update the QUIC library (quic-go et al.) and the server to matching versions.","Verify QUIC transport parameters are sent by the client too (QUIC requires both directions).","Report the missing extension to the QUIC server implementer."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight: confirm this is genuinely a QUIC connection and your QUIC lib is wired up.\n// QUIC mode is entered by the QUIC library; if c.quic == nil you are NOT in QUIC mode.\nif !usingQUIC {\n    return errors.New(\"peer is a QUIC server; use a QUIC transport, not tls.Dial\")\n}","typeGuard":null,"tryCatchPattern":"// QUIC handshake errors surface from the QUIC library wrapping crypto/tls.\n// Check your QUIC library's error type (e.g., quic-go ApplicationError/TransportError).\nif err := qconn.Handshake(); err != nil {\n    var te *qerr.TransportError\n    if errors.As(err, &te) { /* inspect te.ErrorCode */ }\n}","preventionTips":["Use a maintained QUIC library (e.g., quic-go) that correctly drives crypto/tls QUIC mode.","Match client and server QUIC versions.","Never feed a plain TCP connection into QUIC-configured tls.Config."],"tags":["tls","tls13","quic","encrypted-extensions","protocol-violation","network","go"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}