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

  1. Pick a distinct name for extra_keys.host (e.g., "rpc_host") that is not used by any constant_key or header.
  2. 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

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


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)