grpc/grpc-go · error
header key exceeds the maximum length of %d bytes
Error message
header key exceeds the maximum length of %d bytes
What it means
Returned by validateHeaderKey when the key length exceeds maxHeaderSize (16384 bytes). Symmetric to the value-size check in ApplyAdditions, but for the key. Matched by len(key) > maxHeaderSize at extconfig.go:233.
Source
Thrown at internal/xds/httpfilter/extconfig.go:234
}
// validateHeaderKey returns a non-nil error if key may not be mutated by an
// external processing server, either because the key is reserved or because it
// is not a valid gRPC header name.
func validateHeaderKey(key string) error {
switch {
case len(key) == 0:
return fmt.Errorf("header key is empty")
case key[0] == ':':
return fmt.Errorf("header key %q is a pseudo-header", key)
case key == "host":
return fmt.Errorf("header key %q is reserved", key)
case strings.HasPrefix(key, "grpc-"):
return fmt.Errorf("header key %q is in the reserved 'grpc-' space", key)
case key != strings.ToLower(key):
return fmt.Errorf("header key %q is not lowercase", key)
case len(key) > maxHeaderSize:
return fmt.Errorf("header key exceeds the maximum length of %d bytes", maxHeaderSize)
}
return imetadata.ValidateKey(key)
}
func (hmr *HeaderMutationRules) allow(key string) bool {
if hmr.DisallowExpr != nil && hmr.DisallowExpr.MatchString(key) {
return false
}
if hmr.AllowExpr != nil && hmr.AllowExpr.MatchString(key) {
return true
}
if hmr.AllowExpr != nil {
return false
}
return true
}
// ConstructHeaderMap constructs a HeaderMap from the given metadata and rawView on GitHub (pinned to 0c51461d27)
Solutions
- Cap header key length on the ext_proc server (well below 16 KiB; realistic keys are < 100 bytes).
- Validate the key field is a short identifier before emitting.
- If you need a large descriptor, put it in the value (still capped) or the message body.
- Add fuzzing on the server's header construction path.
Example fix
// before
emit(longString, "v")
// after
const maxKeyLen = 1024
if len(longString) > maxKeyLen { return errInvalidKey }
emit(longString, "v") Defensive patterns
Strategy: validation
Validate before calling
// server-side: cap key length
const maxKeyLen = 1024
if len(key) > maxKeyLen { return fmt.Errorf("header key too long") } Prevention
- Cap key length to a small, realistic limit.
- Validate keys are short identifiers, not blobs.
- Fuzz header construction with long inputs.
- Move large descriptors to the value or body.
When it happens
Trigger: The ext_proc server sends a mutation whose header key is longer than 16 KiB. validateHeaderKey fails the size check; in ApplyAdditions this is wrapped as error 441, in ApplyRemovals as error 443.
Common situations: Server builds the key from unbounded user input (e.g. a whole URL or JSON blob used as a key); a serialization bug places the value in the key field; server log/metadata leak into the key.
Related errors
- header key is empty
- invalid header mutation: value for header key %q exceeds the
- header mutation disallowed by headerMutationRules for header
- header mutation disallowed by headerMutationRules for header
- header key %q is a pseudo-header
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/eaa8fdd4734afcd2.
Report an issue: GitHub.