{"record":{"id":"a7df519388f60fe4","repo":"grpc/grpc-go","slug":"rls-invalid-childpolicy-config-no-supported-poli","errorCode":null,"errorMessage":"rls: invalid childPolicy config: no supported policies found in %+v","messagePattern":"rls: invalid childPolicy config: no supported policies found in %\\+v","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/rls/config.go","lineNumber":322,"sourceCode":"\t\t// - unmarshal the raw JSON bytes of the child policy config into a map\n\t\t// - add an entry with key set to `target_field_name` and a dummy value\n\t\t// - marshal the map back to JSON and parse the config using the parser\n\t\t// retrieved previously\n\t\tvar childConfig map[string]json.RawMessage\n\t\tif err := json.Unmarshal(rawCfg, &childConfig); err != nil {\n\t\t\treturn \"\", nil, fmt.Errorf(\"rls: json unmarshal failed for child policy config %q: %v\", string(rawCfg), err)\n\t\t}\n\t\tchildConfig[targetFieldName], _ = json.Marshal(dummyChildPolicyTarget)\n\t\tjsonCfg, err := json.Marshal(childConfig)\n\t\tif err != nil {\n\t\t\treturn \"\", nil, fmt.Errorf(\"rls: json marshal failed for child policy config {%+v}: %v\", childConfig, err)\n\t\t}\n\t\tif _, err := parser.ParseConfig(jsonCfg); err != nil {\n\t\t\treturn \"\", nil, fmt.Errorf(\"rls: childPolicy config validation failed: %v\", err)\n\t\t}\n\t\treturn name, childConfig, nil\n\t}\n\treturn \"\", nil, fmt.Errorf(\"rls: invalid childPolicy config: no supported policies found in %+v\", childPolicies)\n}\n\nfunc convertDuration(d *durationpb.Duration) (time.Duration, error) {\n\tif d == nil {\n\t\treturn 0, nil\n\t}\n\treturn d.AsDuration(), d.CheckValid()\n}\n","sourceCodeStart":304,"sourceCodeEnd":331,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/balancer/rls/config.go#L304-L331","documentation":"parseChildPolicyConfigs iterates the childPolicy list and skips any entry whose name is not a registered balancer (balancer.Get returns nil). If none of the entries resolve to a registered builder, RLS has no valid child to delegate to and rejects the whole config. This also fires when the list is empty.","triggerScenarios":"Every name in childPolicy is misspelled or unregistered (e.g. \"RoundRobin\" instead of \"round_robin\", or a custom LB not yet balancer.Register'd); or childPolicy is an empty array.","commonSituations":"Wrong policy name casing; referencing a balancer from an not-yet-imported package (its init() never ran); xDS producing a child policy list with names the client doesn't know; blank childPolicy.","solutions":["Use a registered policy name such as \"round_robin\", \"pick_first\", or \"weighted_round_robin\".","If using a custom balancer, ensure its package is imported for side effects (blank import) so balancer.Register runs before config parse.","Provide at least one childPolicy entry — the list must not be empty."],"exampleFix":"// before\n\"childPolicy\": [{ \"RoundRobin\": {} }]\n// after\n\"childPolicy\": [{ \"round_robin\": {} }]","handlingStrategy":"validation","validationCode":"func validateAtLeastOneRegisteredChild(childPolicy []map[string]json.RawMessage) error {\n    for _, entry := range childPolicy {\n        for name := range entry {\n            if balancer.Get(name) != nil {\n                return nil\n            }\n        }\n    }\n    return fmt.Errorf(\"no registered child policy found\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use lowercase canonical policy names (round_robin, pick_first).","Blank-import custom balancer packages so registration init() runs.","Never leave childPolicy empty in an RLS config."],"tags":["rls","service-config","config-validation","go","grpc","child-policy"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}