grpc/grpc-go · error
error parsing loadBalancingConfig for policy
Error message
error parsing loadBalancingConfig for policy %q: %v
What it means
Fires at serviceconfig.go:116 when a registered balancer's ConfigParser.ParseConfig rejects the config JSON supplied for its policy in loadBalancingConfig. The wrapper preserves the policy name and the balancer's own error, so this is the inner balancer (e.g. weighted_round_robin, xds) saying its config block is invalid, not a structural problem with the service config itself.
Solutions
- Read the policy name (%q) and the inner %v error to find the exact field the parser rejected.
- Consult that balancer's documentation/schema for the expected config fields and correct them.
- Confirm the balancer is registered (import its package, e.g. _ "google.golang.org/grpc/balancer/weightedroundrobin") so the parser you expect is the one that ran.
- Pin or align client and config-producer versions so the schema matches.
Example fix
// before
// {"loadBalancingConfig": [{"weighted_round_robin": {"children": [{"weight": 10}]}}]}
// // missing required "target" field on child -> ParseConfig fails
// after
// {"loadBalancingConfig": [{"weighted_round_robin": {"children": [
// {"target": "cluster_a", "weight": 10}
// ]}}]} Defensive patterns
Strategy: validation
Validate before calling
// Preflight: ensure every named policy's config parses.
func preflightLBConfig(raw []byte) error {
var bc svcconfig.BalancerConfig
if err := json.Unmarshal(raw, &bc); err != nil {
return err
}
return nil
} Try / catch
var bc svcconfig.BalancerConfig
if err := json.Unmarshal(raw, &bc); err != nil {
if strings.Contains(err.Error(), "error parsing loadBalancingConfig") {
// inner balancer rejected its config; check the policy name + inner error
}
return err
} Prevention
- Blank-import the balancer packages you reference so the right ConfigParser runs.
- Keep config-producer and client versions aligned to avoid schema drift.
- Read the specific balancer's config schema (e.g. weightedroundrobin, xds) before authoring.
When it happens
Trigger: Calling Dial with a service config whose loadBalancingConfig names a registered policy whose config object fails that policy's parser. Examples: weighted_round_robin with a child entry missing the weight field, xds config with an unknown field under strict parsing, or any policy whose JSON doesn't match its expected schema.
Common situations: Upgrading gRPC and a balancer's config schema changed (renamed/required fields); using an xDS-generated config against a client version that expects a different shape; typos in field names within a policy's config block.
Related errors
- invalid loadBalancingConfig: entry
- invalid loadBalancingConfig: no supported policies found in
- did not find the cluster
- duplicated name
- error parsing Outlier Detection config
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/ecb1e3dc29e6028f.
Report an issue: GitHub.
Appendix: source
Thrown at internal/serviceconfig/serviceconfig.go:116
if builder == nil {
// If the balancer is not registered, move on to the next config.
// This is not an error.
continue
}
bc.Name = name
parser, ok := builder.(balancer.ConfigParser)
if !ok {
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 *boolView on GitHub (pinned to 0c51461d27)