grpc/grpc-go · error
invalid loadBalancingConfig: no supported policies found in
Error message
invalid loadBalancingConfig: no supported policies found in %v
What it means
This error occurs when the loadBalancingConfig array in a service config was iterated completely, but none of the listed policy names matched a registered balancer. gRPC treats this as an invalid config because it cannot select any load balancing policy to use.
Source
Thrown at internal/serviceconfig/serviceconfig.go:125
if string(jsonCfg) != "{}" {
logger.Warningf("non-empty balancer configuration %q, but balancer does not implement ParseConfig", string(jsonCfg))
}
// Stop at this, though the builder doesn't support parsing config.
return nil
}
cfg, err := parser.ParseConfig(jsonCfg)
if err != nil {
return fmt.Errorf("error parsing loadBalancingConfig for policy %q: %v", name, err)
}
bc.Config = cfg
return nil
}
// This is reached when the for loop iterates over all entries, but didn't
// return. This means we had a loadBalancingConfig slice but did not
// encounter a registered policy. The config is considered invalid in this
// case.
return fmt.Errorf("invalid loadBalancingConfig: no supported policies found in %v", names)
}
// MethodConfig defines the configuration recommended by the service providers for a
// particular method.
type MethodConfig struct {
// WaitForReady indicates whether RPCs sent to this method should wait until
// the connection is ready by default (!failfast). The value specified via the
// gRPC client API will override the value set here.
WaitForReady *bool
// Timeout is the default timeout for RPCs sent to this method. The actual
// deadline used will be the minimum of the value specified here and the value
// set by the application via the gRPC client API. If either one is not set,
// then the other will be used. If neither is set, then the RPC has no deadline.
Timeout *time.Duration
// MaxReqSize is the maximum allowed payload size for an individual request in a
// stream (client->server) in bytes. The size which is measured is the serialized
// payload after per-message compression (but before stream compression) in bytes.
// The actual value used is the minimum of the value specified here and the value setView on GitHub (pinned to 03255a9237)
Solutions
- Ensure at least one listed policy is registered: import the balancer package (e.g., _ "google.golang.org/grpc/balancer/roundrobin") so its init() registers it.
- Add a well-known fallback policy (e.g., "pick_first" or "round_robin") to the loadBalancingConfig array so the client always finds a supported one.
- Verify the policy name spelling matches the registered name exactly (case-sensitive).
Example fix
// before (broken): only an unregistered policy is listed
"loadBalancingConfig": [{"custom_lb": {}}]
// after (valid): add a registered fallback
"loadBalancingConfig": [{"custom_lb": {}}, {"round_robin": {}}] Defensive patterns
Strategy: validation
Validate before calling
// Check that at least one listed policy is registered before applying config
func hasRegisteredBalancer(raw []byte) bool {
var entries []map[string]json.RawMessage
if json.Unmarshal(raw, &entries) != nil { return false }
for _, e := range entries {
for name := range e {
if balancer.Get(name) != nil { return true }
}
}
return false
} Try / catch
var bc serviceconfig.BalancerConfig
if err := json.Unmarshal(raw, &bc); err != nil {
if strings.Contains(err.Error(), "no supported policies found") {
// ensure required balancers are imported
_ = balancer.Get // force check
}
} Prevention
- Always import balancer packages (blank import) for policies referenced in service config.
- Include a standard fallback policy (round_robin, pick_first) in every loadBalancingConfig.
- Run integration tests that verify service config application with the production binary.
When it happens
Trigger: A service config lists only balancer names that are not registered in the running gRPC process, e.g., only "grpclb" when the grpclb balancer was never imported/registered, or only custom policy names not linked into the binary.
Common situations: Using a gRPC build that doesn't include a required balancer (e.g., xds/rls not imported), version skew between control plane and client, or migrating to a new balancer name before the client supports it.
Related errors
- invalid loadBalancingConfig: entry %v does not contain exact
- error parsing loadBalancingConfig for policy %q: %v
- no SubConn is available
- bad resolver state
- least-request: unable to unmarshal LBConfig: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/3ea577954e9b6415.
Report an issue: GitHub.