{"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":"exception","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/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clusterspecifier/rls/rls.go#L70-L96","documentation":"The RLS load balancer policy named 'rls_experimental' is not found in the gRPC balancer registry (rls.go:86-88). The cluster specifier plugin calls balancer.Get to locate the RLS LB policy for config validation, and a nil return means no balancer with that name has registered itself via init().","triggerScenarios":"balancer.Get(internal.RLSLoadBalancingPolicyName) returns nil because the RLS balancer package (google.golang.org/grpc/balancer/rls) was never imported, so its init() function that calls balancer.Register never executed.","commonSituations":"Application imports the RLS cluster specifier plugin but not the RLS balancer package; using a stripped-down or custom gRPC build that excludes the RLS balancer; build tags or constraints stripping the balancer/rls package; init ordering issue.","solutions":["Add a blank import of the RLS balancer: import _ \"google.golang.org/grpc/balancer/rls\"","Verify the import appears before any xDS resource processing occurs","Check that build tags or build constraints are not excluding the balancer/rls package","Confirm the gRPC version includes the RLS balancer (available since gRPC 1.40+)"],"exampleFix":"// before — RLS cluster specifier imported but not the RLS balancer\nimport (\n    _ \"google.golang.org/grpc/internal/xds/clusterspecifier/rls\"\n)\n\n// after — also import the RLS balancer to register it\nimport (\n    _ \"google.golang.org/grpc/balancer/rls\"\n    _ \"google.golang.org/grpc/internal/xds/clusterspecifier/rls\"\n)","handlingStrategy":"validation","validationCode":"// Verify the RLS LB policy is registered at startup.\nif balancer.Get(internal.RLSLoadBalancingPolicyName) == nil {\n    log.Fatal(\"RLS LB policy not registered — add: import _ \\\"google.golang.org/grpc/balancer/rls\\\"\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always import both the RLS cluster specifier plugin and the RLS balancer package together","Add a startup assertion that checks critical balancer registrations","Review import lists when adding xDS RLS support to ensure all dependencies are included","Use a centralized import file for xDS-related blank imports"],"tags":["rls","xds","balancer","registration","init"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}