{"record":{"id":"e021edf7b970a72e","repo":"grpc/grpc-go","slug":"rls-grpckeybuilder-in-routelookupconfig-contains-e021ed","errorCode":null,"errorMessage":"rls: GrpcKeyBuilder in RouteLookupConfig contains repeated Name field {%+v}","messagePattern":"rls: GrpcKeyBuilder in RouteLookupConfig contains repeated Name field (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/rls/internal/keys/builder.go","lineNumber":98,"sourceCode":"\t\t}\n\n\t\t// Store the builder created above in the BuilderMap based on the value\n\t\t// of the `Names` field, which wraps incoming request's service and\n\t\t// method. Also, ensure that there are no repeated `Names` field.\n\t\tnames := kb.GetNames()\n\t\tif len(names) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"rls: GrpcKeyBuilder in RouteLookupConfig does not contain any Name {%+v}\", kbs)\n\t\t}\n\t\tfor _, name := range names {\n\t\t\tif name.GetService() == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"rls: GrpcKeyBuilder in RouteLookupConfig contains a Name field with no Service {%+v}\", kbs)\n\t\t\t}\n\t\t\tif strings.Contains(name.GetMethod(), `/`) {\n\t\t\t\treturn nil, fmt.Errorf(\"rls: GrpcKeyBuilder in RouteLookupConfig contains a method with a slash {%+v}\", kbs)\n\t\t\t}\n\t\t\tpath := \"/\" + name.GetService() + \"/\" + name.GetMethod()\n\t\t\tif _, ok := bm[path]; ok {\n\t\t\t\treturn nil, fmt.Errorf(\"rls: GrpcKeyBuilder in RouteLookupConfig contains repeated Name field {%+v}\", kbs)\n\t\t\t}\n\t\t\tbm[path] = b\n\t\t}\n\t}\n\treturn bm, nil\n}\n\n// KeyMap represents the RLS keys to be used for a request.\ntype KeyMap struct {\n\t// Map is the representation of an RLS key as a Go map. This is used when\n\t// an actual RLS request is to be sent out on the wire, since the\n\t// RouteLookupRequest proto expects a Go map.\n\tMap map[string]string\n\t// Str is the representation of an RLS key as a string, sorted by keys.\n\t// Since the RLS keys are part of the cache key in the request cache\n\t// maintained by the RLS balancer, and Go maps cannot be used as keys for\n\t// Go maps (the cache is implemented as a map), we need a stringified\n\t// version of it.","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/balancer/rls/internal/keys/builder.go#L80-L116","documentation":"The RLS BuilderMap is keyed by request path (\"/service/method\" or \"/service/\"). Two GrpcKeyBuilder Names that resolve to the same path are ambiguous, so MakeBuilderMap rejects the second one (builder.go:96-99). This keeps a deterministic one-builder-per-path mapping so RLS keys are unambiguous.","triggerScenarios":"Two Names across one or more GrpcKeyBuilders produce the same path string. E.g., one builder declares {Service:\"S\", Method:\"M\"} and another declares {Service:\"S\"} (service-wide); both expand to overlapping paths, or two entries expand to the identical \"/S/M\".","commonSituations":"Adding a new key builder without checking the existing paths; merging configs from two teams; declaring both a service-wide and a method-specific builder for the same service.","solutions":["List every path your GrpcKeyBuilders produce and remove the duplicate so each path appears exactly once.","If you need service-wide plus method-specific behavior, use distinct services or methods, or consolidate into a single builder with the desired header matchers."],"exampleFix":"// before\nkb1.Names = []*rlspb.Name{{Service: \"S\", Method: \"M\"}}\nkb2.Names = []*rlspb.Name{{Service: \"S\", Method: \"M\"}} // duplicate path /S/M\n// after\nkb2.Names = []*rlspb.Name{{Service: \"S\", Method: \"Other\"}}","handlingStrategy":"validation","validationCode":"func validateNoDuplicatePaths(cfg *rlspb.RouteLookupConfig) error {\n\tpaths := map[string]bool{}\n\tfor _, kb := range cfg.GetGrpcKeybuilders() {\n\t\tfor _, n := range kb.GetNames() {\n\t\t\tp := \"/\" + n.GetService() + \"/\" + n.GetMethod()\n\t\t\tif paths[p] { return fmt.Errorf(\"duplicate path %q\", p) }\n\t\t\tpaths[p] = true\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Maintain the set of paths your builders cover; reject duplicates during config authoring.","Avoid mixing service-wide and method-specific builders for the same service.","Test with keys.MakeBuilderMap to surface overlaps."],"tags":["go","grpc","rls","config","validation","balancer"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}