{"record":{"id":"5f6f2e086c273551","repo":"golang/go","slug":"tls-invalid-outer-extensions","errorCode":null,"errorMessage":"tls: invalid outer extensions","messagePattern":"tls: invalid outer extensions","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/ech.go","lineNumber":337,"sourceCode":"\t\t\t\tif !extensions.ReadUint16(&extension) ||\n\t\t\t\t\t!extensions.ReadUint16LengthPrefixed(&extData) {\n\t\t\t\t\trecon.SetError(errors.New(\"tls: invalid inner client hello\"))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif extension == extensionECHOuterExtensions {\n\t\t\t\t\tif !extData.ReadUint8LengthPrefixed(&extData) {\n\t\t\t\t\t\trecon.SetError(errors.New(\"tls: invalid inner client hello\"))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tvar i int\n\t\t\t\t\tfor !extData.Empty() {\n\t\t\t\t\t\tvar extType uint16\n\t\t\t\t\t\tif !extData.ReadUint16(&extType) {\n\t\t\t\t\t\t\trecon.SetError(errors.New(\"tls: invalid inner client hello\"))\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif extType == extensionEncryptedClientHello {\n\t\t\t\t\t\t\trecon.SetError(errors.New(\"tls: invalid outer extensions\"))\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor ; i <= len(rawOuterExts); i++ {\n\t\t\t\t\t\t\tif i == len(rawOuterExts) {\n\t\t\t\t\t\t\t\trecon.SetError(errors.New(\"tls: invalid outer extensions\"))\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif rawOuterExts[i].extType == extType {\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\trecon.AddUint16(rawOuterExts[i].extType)\n\t\t\t\t\t\trecon.AddUint16LengthPrefixed(func(recon *cryptobyte.Builder) {\n\t\t\t\t\t\t\trecon.AddBytes(rawOuterExts[i].data)\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\trecon.AddUint16(extension)","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/ech.go#L319-L355","documentation":"Thrown during ECH inner ClientHello reconstruction when the outer_extensions compressed reference list includes the encrypted_client_hello extension type. RFC 9460 explicitly forbids this because the inner ClientHello carries its own ECH indicator (a single byte set to innerECHExt=1), and referencing the outer ECH extension would create ambiguity and potential security issues.","triggerScenarios":"The inner ClientHello's outer_extensions list contains the extensionEncryptedClientHello type ID, which is prohibited by the ECH specification.","commonSituations":"A non-compliant ECH client implementation that incorrectly includes the ECH extension in the compressed outer extensions reference. A deliberate protocol violation attempt. A client using an incompatible ECH draft version with different rules.","solutions":["Ensure the ECH client implementation excludes encrypted_client_hello from the outer_extensions compressed list — this is explicitly forbidden by RFC 9460","Update the client ECH library to the latest version that handles the inner/outer extension separation correctly","If using a custom ECH implementation, verify that the extension compression logic filters out the ECH extension type","Report as a bug to the client library vendor if using a third-party ECH implementation"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Wrapped into errInvalidECHExt by processECHClientHello.","preventionTips":["Ensure ECH client excludes encrypted_client_hello from the outer_extensions list (RFC 9460 requirement)","Update client ECH libraries to RFC 9460-compliant versions","Audit custom ECH implementations for this specific protocol violation"],"tags":["tls","ech","server-side","handshake","extensions","security","rfc-9460"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}