{"record":{"id":"fdf1eb955f84556d","repo":"golang/go","slug":"tls-invalid-nextprotos-value","errorCode":null,"errorMessage":"tls: invalid NextProtos value","messagePattern":"tls: invalid NextProtos value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client.go","lineNumber":53,"sourceCode":"\tserverHello  *serverHelloMsg\n\thello        *clientHelloMsg\n\tsuite        *cipherSuite\n\tfinishedHash finishedHash\n\tmasterSecret []byte\n\tsession      *SessionState // the session being resumed\n\tticket       []byte        // a fresh ticket received during this handshake\n}\n\nfunc (c *Conn) makeClientHello() (*clientHelloMsg, *keySharePrivateKeys, *echClientContext, error) {\n\tconfig := c.config\n\tif len(config.ServerName) == 0 && !config.InsecureSkipVerify {\n\t\treturn nil, nil, nil, errors.New(\"tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config\")\n\t}\n\n\tnextProtosLength := 0\n\tfor _, proto := range config.NextProtos {\n\t\tif l := len(proto); l == 0 || l > 255 {\n\t\t\treturn nil, nil, nil, errors.New(\"tls: invalid NextProtos value\")\n\t\t} else {\n\t\t\tnextProtosLength += 1 + l\n\t\t}\n\t}\n\tif nextProtosLength > 0xffff {\n\t\treturn nil, nil, nil, errors.New(\"tls: NextProtos values too large\")\n\t}\n\n\tsupportedVersions := config.supportedVersions(roleClient, c.quic != nil)\n\tif len(supportedVersions) == 0 {\n\t\treturn nil, nil, nil, errors.New(\"tls: no supported versions satisfy MinVersion and MaxVersion\")\n\t}\n\t// Since supportedVersions is sorted in descending order, the first element\n\t// is the maximum version and the last element is the minimum version.\n\tmaxVersion := supportedVersions[0]\n\tminVersion := supportedVersions[len(supportedVersions)-1]\n\n\thello := &clientHelloMsg{","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client.go#L35-L71","documentation":"Thrown by makeClientHello when any entry in config.NextProtos (the ALPN protocol ID list) has a length of 0 or exceeds 255 bytes. ALPN protocol IDs are encoded with a single-byte length prefix on the wire, so each must be between 1 and 255 bytes long. An empty string or an excessively long protocol name violates this constraint.","triggerScenarios":"Setting config.NextProtos to a slice containing an empty string (e.g., []string{\"h2\", \"\"}) or a string longer than 255 bytes (e.g., []string{strings.Repeat(\"a\", 300)}).","commonSituations":"Accidentally including an empty string from a comma-split or whitespace-trim operation. Programmatically generated protocol names that exceed 255 bytes. A configuration file with a trailing comma producing an empty entry. Accidental nil interface conversion producing an empty string.","solutions":["Remove empty strings from config.NextProtos before use","Ensure each ALPN protocol ID is between 1 and 255 bytes long","Filter the NextProtos list programmatically: slices.DeleteFunc(nextProtos, func(s string) bool { return len(s) == 0 || len(s) > 255 })","Validate ALPN entries from external input (config files, user input) before assigning to NextProtos"],"exampleFix":"// before\nconfig := &tls.Config{\n    NextProtos: []string{\"h2\", \"\", \"http/1.1\"}, // empty string → error\n}\n// after\nconfig := &tls.Config{\n    NextProtos: []string{\"h2\", \"http/1.1\"},\n}","handlingStrategy":"validation","validationCode":"func validateNextProtos(protos []string) error {\n    for _, p := range protos {\n        if l := len(p); l == 0 || l > 255 {\n            return fmt.Errorf(\"invalid ALPN protocol length %d: must be 1-255 bytes\", l)\n        }\n    }\n    return nil\n}\n\n// Usage:\n//   if err := validateNextProtos(config.NextProtos); err != nil {\n//       log.Fatal(err)\n//   }","typeGuard":null,"tryCatchPattern":"// Pre-validate before assigning to config:\n//\n//   protos := slices.DeleteFunc(rawProtos, func(s string) bool {\n//       return len(s) == 0 || len(s) > 255\n//   })\n//   config.NextProtos = protos","preventionTips":["Filter empty strings from NextProtos before assignment","Validate ALPN entries from config files or user input","Use constants for well-known protocol IDs (e.g., \"h2\", \"http/1.1\") instead of dynamic strings"],"tags":["tls","client-side","config","alpn"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}