grpc/grpc-go · error
RLS LB policy not registered
Error message
RLS LB policy not registered
What it means
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.
Source
Thrown at internal/xds/clusterspecifier/rls/rls.go:88
}
lbCfgJSON := &lbConfigJSON{
RouteLookupConfig: rlcJSON, // "JSON form of RouteLookupClusterSpecifier.config" - RLS in xDS Design Doc
ChildPolicy: []map[string]json.RawMessage{
{
"cds_experimental": json.RawMessage(`{"isDynamic":true}`),
},
},
ChildPolicyConfigTargetFieldName: "cluster",
}
rawJSON, err := json.Marshal(lbCfgJSON)
if err != nil {
return nil, fmt.Errorf("rls_csp: error marshaling load balancing config %v: %v", lbCfgJSON, err)
}
rlsBB := balancer.Get(internal.RLSLoadBalancingPolicyName)
if rlsBB == nil {
return nil, fmt.Errorf("RLS LB policy not registered")
}
if _, err = rlsBB.(balancer.ConfigParser).ParseConfig(rawJSON); err != nil {
return nil, fmt.Errorf("rls_csp: validation error from rls lb policy parsing: %v", err)
}
return clusterspecifier.BalancerConfig{{internal.RLSLoadBalancingPolicyName: lbCfgJSON}}, nil
}
View on GitHub (pinned to 03255a9237)
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.
Example fix
// before: only the cluster specifier is imported import _ "google.golang.org/grpc/internal/xds/clusterspecifier/rls" // after: also register the RLS balancer import ( _ "google.golang.org/grpc/balancer/rls" _ "google.golang.org/grpc/internal/xds/clusterspecifier/rls" )
Defensive patterns
Strategy: validation
Validate before calling
// At startup, confirm the RLS balancer is registered.
func ensureRLSBalancerRegistered() error {
if balancer.Get(internal.RLSLoadBalancingPolicyName) == nil {
return errors.New("RLS balancer not registered; blank-import the rls balancer package")
}
return nil
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- rls_csp: validation error from rls lb policy parsing: %v
- no ResourceType implementation found for typeURL %q
- rls_csp: nil configuration message provided
- rls_csp: error parsing config %v: unknown type %T
- rls_csp: error parsing config %v: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/c924555ac819058d.
Report an issue: GitHub.