{"record":{"id":"0c974b7d3aff819d","repo":"golang/go","slug":"tls-invalid-reconstructed-inner-client-hello","errorCode":null,"errorMessage":"tls: invalid reconstructed inner client hello","messagePattern":"tls: invalid reconstructed inner client hello","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/ech.go","lineNumber":370,"sourceCode":"\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)\n\t\t\t\t\trecon.AddUint16LengthPrefixed(func(recon *cryptobyte.Builder) {\n\t\t\t\t\t\trecon.AddBytes(extData)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t})\n\n\treconBytes, err := recon.Bytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tinner := &clientHelloMsg{}\n\tif !inner.unmarshal(reconBytes) {\n\t\treturn nil, errors.New(\"tls: invalid reconstructed inner client hello\")\n\t}\n\n\tif !bytes.Equal(inner.encryptedClientHello, []byte{uint8(innerECHExt)}) {\n\t\treturn nil, errInvalidECHExt\n\t}\n\n\thasTLS13 := false\n\tfor _, v := range inner.supportedVersions {\n\t\t// Skip GREASE values (values of the form 0x?A0A).\n\t\t// GREASE (Generate Random Extensions And Sustain Extensibility) is a mechanism used by\n\t\t// browsers like Chrome to ensure TLS implementations correctly ignore unknown values.\n\t\t// GREASE values follow a specific pattern: 0x?A0A, where ? can be any hex digit.\n\t\t// These values should be ignored when processing supported TLS versions.\n\t\tif v&0x0F0F == 0x0A0A && v&0xff == v>>8 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Ensure at least TLS 1.3 is offered.","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/ech.go#L352-L388","documentation":"Thrown after ECH inner ClientHello reconstruction when the fully reassembled bytes (decrypted inner fields plus expanded outer extensions substituted in) fail to parse as a valid ClientHello via clientHelloMsg.unmarshal(). This is a comprehensive final validation that catches inconsistencies not detected by earlier field-level checks, such as duplicate extensions, invalid field values, or structural contradictions introduced during extension expansion.","triggerScenarios":"The reconstructed inner ClientHello — assembled from decrypted inner content with outer_extensions expanded to their full extension data from the outer hello — contains data that fails the complete ClientHello parser. Possible causes: duplicate extension types after expansion, invalid cipher suite values, unsupported version fields, or extension data that is individually valid but collectively contradictory.","commonSituations":"The expansion of outer extensions introduced a duplicate extension that also exists in the inner-only set. The outer hello's extension data is incompatible with the inner hello's structure. A client bug where the inner and outer hello share an extension with conflicting values. Decryption corruption that produces fields valid individually but invalid collectively.","solutions":["Ensure the ECH client does not duplicate extensions between the inner-only set and the outer_extensions compressed reference","Verify that all extension data in the outer hello is consistent with the inner hello's fields (e.g., supported_versions, key_share, etc.)","Check for extension type collisions between inner and outer extension sets","Test the client against a reference server implementation to identify reconstruction failures"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Wrapped into errInvalidECHExt by processECHClientHello.","preventionTips":["Ensure no duplicate extensions exist between the inner-only set and the outer_extensions compressed references","Verify inner and outer hello extension data is mutually consistent","Test the full reconstruction path with reference ECH clients"],"tags":["tls","ech","server-side","handshake","reconstruction","parsing"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}