grpc/grpc-go · error
rls: GrpcKeyBuilder in RouteLookupConfig contains repeated…
Error message
rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q in extra_keys from constant_keys or headers {%+v} What it means
GrpcKeyBuilder.extra_keys lets you add the request host (extra_keys.host) as a key in the RLS request. grpc-go requires the host key name to differ from every key already claimed by constant_keys or headers (builder.go:65-66). If extra_keys.host equals an existing key in seenKeys, MakeBuilderMap rejects the config.
Solutions
- Pick a distinct name for extra_keys.host (e.g., "rpc_host") that is not used by any constant_key or header.
- Or remove the constant_key/header that collides if the host value should override it.
Example fix
// before
kb := &rlspb.GrpcKeyBuilder{
ConstantKeys: map[string]string{"host": "localhost"},
ExtraKeys: &rlspb.GrpcKeyBuilder_ExtraKeys{Host: "host"},
}
// after
kb := &rlspb.GrpcKeyBuilder{
ConstantKeys: map[string]string{"host": "localhost"},
ExtraKeys: &rlspb.GrpcKeyBuilder_ExtraKeys{Host: "rpc_host"}, // distinct name
} Defensive patterns
Strategy: validation
Validate before calling
func validateExtraKeysUnique(cfg *rlspb.RouteLookupConfig) error {
for _, kb := range cfg.GetGrpcKeybuilders() {
seen := map[string]bool{}
for k := range kb.GetConstantKeys() { seen[k] = true }
for _, h := range kb.GetHeaders() { seen[h.GetKey()] = true }
if h := kb.GetExtraKeys().GetHost(); h != "" && seen[h] {
return fmt.Errorf("extra_keys.host %q duplicates a constant/header key", h)
}
}
return nil
} Prevention
- Namespace extra_keys fields (e.g., rpc_host, rpc_service, rpc_method) to avoid colliding with header/constant key names.
- When adding extra_keys to an existing builder, re-check constant_keys and headers for collisions.
- Test the config through keys.MakeBuilderMap.
When it happens
Trigger: A GrpcKeyBuilder has extra_keys.host = "host" while constant_keys or a header already uses the key name "host". The check at builder.go:65 finds it in seenKeys and returns this error.
Common situations: Adding host as an extra key after a constant key or header already claimed the name "host"; copying a template config and forgetting to namespace the extra_keys.
Related errors
- rls: GrpcKeyBuilder in RouteLookupConfig contains repeated…
- rls: GrpcKeyBuilder in RouteLookupConfig contains a Name…
- rls: GrpcKeyBuilder in RouteLookupConfig contains repeated…
- rls: GrpcKeyBuilder in RouteLookupConfig contains a method…
- rls: GrpcKeyBuilder in RouteLookupConfig does not contain…
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/a08c3046c5ce30c0.
Report an issue: GitHub.
Appendix: source
Thrown at balancer/rls/internal/keys/builder.go:66
var matchers []matcher
seenKeys := make(map[string]bool)
constantKeys := kb.GetConstantKeys()
for k := range kb.GetConstantKeys() {
seenKeys[k] = true
}
for _, h := range kb.GetHeaders() {
if h.GetRequiredMatch() {
return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig has required_match field set {%+v}", kbs)
}
key := h.GetKey()
if seenKeys[key] {
return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q across headers, constant_keys and extra_keys {%+v}", key, kbs)
}
seenKeys[key] = true
matchers = append(matchers, matcher{key: h.GetKey(), names: h.GetNames()})
}
if seenKeys[kb.GetExtraKeys().GetHost()] {
return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q in extra_keys from constant_keys or headers {%+v}", kb.GetExtraKeys().GetHost(), kbs)
}
if seenKeys[kb.GetExtraKeys().GetService()] {
return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q in extra_keys from constant_keys or headers {%+v}", kb.GetExtraKeys().GetService(), kbs)
}
if seenKeys[kb.GetExtraKeys().GetMethod()] {
return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q in extra_keys from constant_keys or headers {%+v}", kb.GetExtraKeys().GetMethod(), kbs)
}
b := builder{
headerKeys: matchers,
constantKeys: constantKeys,
hostKey: kb.GetExtraKeys().GetHost(),
serviceKey: kb.GetExtraKeys().GetService(),
methodKey: kb.GetExtraKeys().GetMethod(),
}
// Store the builder created above in the BuilderMap based on the value
// of the `Names` field, which wraps incoming request's service and
// method. Also, ensure that there are no repeated `Names` field.View on GitHub (pinned to 0c51461d27)