{"record":{"id":"c924555ac819058d","repo":"grpc/grpc-go","slug":"rls-lb-policy-not-registered","errorCode":null,"errorMessage":"RLS LB policy not registered","messagePattern":"RLS LB policy not registered","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clusterspecifier/rls/rls.go","lineNumber":88,"sourceCode":"\t}\n\tlbCfgJSON := &lbConfigJSON{\n\t\tRouteLookupConfig: rlcJSON, // \"JSON form of RouteLookupClusterSpecifier.config\" - RLS in xDS Design Doc\n\t\tChildPolicy: []map[string]json.RawMessage{\n\t\t\t{\n\t\t\t\t\"cds_experimental\": json.RawMessage(`{\"isDynamic\":true}`),\n\t\t\t},\n\t\t},\n\t\tChildPolicyConfigTargetFieldName: \"cluster\",\n\t}\n\n\trawJSON, err := json.Marshal(lbCfgJSON)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rls_csp: error marshaling load balancing config %v: %v\", lbCfgJSON, err)\n\t}\n\n\trlsBB := balancer.Get(internal.RLSLoadBalancingPolicyName)\n\tif rlsBB == nil {\n\t\treturn nil, fmt.Errorf(\"RLS LB policy not registered\")\n\t}\n\tif _, err = rlsBB.(balancer.ConfigParser).ParseConfig(rawJSON); err != nil {\n\t\treturn nil, fmt.Errorf(\"rls_csp: validation error from rls lb policy parsing: %v\", err)\n\t}\n\n\treturn clusterspecifier.BalancerConfig{{internal.RLSLoadBalancingPolicyName: lbCfgJSON}}, nil\n}\n","sourceCodeStart":70,"sourceCodeEnd":96,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/clusterspecifier/rls/rls.go#L70-L96","documentation":"Returned by ParseClusterSpecifierConfig when balancer.Get(internal.RLSLoadBalancingPolicyName) returns nil, meaning the RLS load balancer policy was never registered with the gRPC balancer registry. Without it, the cluster specifier cannot validate or build the child policy, so the config is rejected.","triggerScenarios":"The binary imports the RLS cluster specifier plugin but does not import/register the RLS balancer package (blank import of the rls balancer). The plugin's init() registers itself, but the balancer it depends on is registered separately.","commonSituations":"A custom binary or test that pulls in xds/clusterspecifier/rls without the corresponding balancer/rls package, or a build that uses build tags/linker flags that drop the RLS balancer registration.","solutions":["Add a blank import of the RLS balancer package in your main package (e.g. _ \"google.golang.org/grpc/balancer/rls\").","Verify the import is not dead-code-eliminated (call balancer.Get at startup to confirm registration).","Check gRPC version: the RLS balancer name constant must match internal.RLSLoadBalancingPolicyName in your grpc-go version."],"exampleFix":"// before: only the cluster specifier is imported\nimport _ \"google.golang.org/grpc/internal/xds/clusterspecifier/rls\"\n\n// after: also register the RLS balancer\nimport (\n  _ \"google.golang.org/grpc/balancer/rls\"\n  _ \"google.golang.org/grpc/internal/xds/clusterspecifier/rls\"\n)","handlingStrategy":"validation","validationCode":"// At startup, confirm the RLS balancer is registered.\nfunc ensureRLSBalancerRegistered() error {\n    if balancer.Get(internal.RLSLoadBalancingPolicyName) == nil {\n        return errors.New(\"RLS balancer not registered; blank-import the rls balancer package\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Blank-import the RLS balancer package wherever you use the RLS cluster specifier.","Add a startup check that balancer.Get returns non-nil for the RLS policy.","Verify the balancer name constant matches your grpc-go version."],"tags":["grpc","xds","rls","balancer","registration"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}