golang/go · error
tls: NextProtos values too large
Error message
tls: NextProtos values too large
What it means
Thrown by makeClientHello when the total serialized size of all config.NextProtos entries (including 1-byte length prefix per entry) exceeds 65535 bytes (0xFFFF). The ALPN extension encodes the protocol list with a uint16 overall length prefix, capping the total at 64KB. This is unlikely with normal usage but possible with many or very large protocol IDs.
Source
Thrown at src/crypto/tls/handshake_client.go:59
ticket []byte // a fresh ticket received during this handshake
}
func (c *Conn) makeClientHello() (*clientHelloMsg, *keySharePrivateKeys, *echClientContext, error) {
config := c.config
if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
return nil, nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
}
nextProtosLength := 0
for _, proto := range config.NextProtos {
if l := len(proto); l == 0 || l > 255 {
return nil, nil, nil, errors.New("tls: invalid NextProtos value")
} else {
nextProtosLength += 1 + l
}
}
if nextProtosLength > 0xffff {
return nil, nil, nil, errors.New("tls: NextProtos values too large")
}
supportedVersions := config.supportedVersions(roleClient, c.quic != nil)
if len(supportedVersions) == 0 {
return nil, nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
}
// Since supportedVersions is sorted in descending order, the first element
// is the maximum version and the last element is the minimum version.
maxVersion := supportedVersions[0]
minVersion := supportedVersions[len(supportedVersions)-1]
hello := &clientHelloMsg{
vers: maxVersion,
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
extendedMasterSecret: true,
ocspStapling: true,
scts: true,View on GitHub (pinned to b6b368adc5)
Solutions
- Reduce the number of entries or the length of individual entries in config.NextProtos
- Remove unnecessary or duplicate ALPN protocol IDs — typically only 2-3 are needed (e.g., "h2", "http/1.1")
- Validate total size before assignment: ensure sum of (1 + len(proto)) for all entries is at most 65535
- Cap external input that feeds into NextProtos to a reasonable maximum
Example fix
// before — overly large protocol list
config := &tls.Config{
NextProtos: generateLargeProtocolList(), // total > 64KB
}
// after — trim to essential protocols
config := &tls.Config{
NextProtos: []string{"h2", "http/1.1"},
} Defensive patterns
Strategy: validation
Validate before calling
func validateNextProtosSize(protos []string) error {
total := 0
for _, p := range protos {
total += 1 + len(p)
}
if total > 0xffff {
return fmt.Errorf("total NextProtos size %d exceeds 65535 bytes", total)
}
return nil
} Try / catch
// Pre-validate total size:
//
// if err := validateNextProtosSize(config.NextProtos); err != nil {
// config.NextProtos = config.NextProtos[:2] // trim to essential protocols
// } Prevention
- Keep NextProtos to a small set of standard ALPN IDs (typically 2-3 entries)
- Avoid programmatically generating large protocol lists
- Cap external input feeding into NextProtos
When it happens
Trigger: Setting config.NextProtos to a slice where the sum of (1 + len(proto)) for all entries exceeds 0xFFFF (65535).
Common situations: Accidentally duplicating entries many times in a loop. Including extremely long protocol ID strings. A programming error that appends a large data structure as protocol names. Generating NextProtos from unbounded external input without size limits.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: invalid NextProtos value
- tls: either ServerName or InsecureSkipVerify must be specifi
- tls: no supported versions satisfy MinVersion and MaxVersion
- tls: short read from Rand:
- tls: no supported key exchange methods (CurveIDs)
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/b8f584605060326d.
Report an issue: GitHub.