grpc/grpc-go · error
xds_wrr_locality: invalid LBConfig: child policy field must
Error message
xds_wrr_locality: invalid LBConfig: child policy field must be set
What it means
Returned by the xds_wrr_locality balancer's ParseConfig (wrrlocality/balancer.go:97-98) when the JSON LB config unmarshals to nil or its ChildPolicy field is nil. The weighted-round-robin-per-locality balancer delegates to the weighted_target child, so a missing child_policy makes the config unusable and is rejected at parse time.
Source
Thrown at internal/xds/balancer/wrrlocality/balancer.go:98
return nil
}
wrrL := &wrrLocalityBalancer{
child: wtb,
childParser: wtbCfgParser,
}
wrrL.logger = prefixLogger(wrrL)
wrrL.logger.Infof("Created")
return wrrL
}
func (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
var lbCfg *LBConfig
if err := json.Unmarshal(s, &lbCfg); err != nil {
return nil, fmt.Errorf("xds_wrr_locality: invalid LBConfig: %s, error: %v", string(s), err)
}
if lbCfg == nil || lbCfg.ChildPolicy == nil {
return nil, errors.New("xds_wrr_locality: invalid LBConfig: child policy field must be set")
}
return lbCfg, nil
}
type attributeKey struct{}
// Equal allows the values to be compared by Attributes.Equal.
func (a AddrInfo) Equal(o any) bool {
oa, ok := o.(AddrInfo)
return ok && oa.LocalityWeight == a.LocalityWeight
}
// AddrInfo is the locality weight of the locality an address is a part of.
type AddrInfo struct {
LocalityWeight uint32
}
// SetAddrInfo returns a copy of endpoint in which the Attributes field isView on GitHub (pinned to 03255a9237)
Solutions
- Add a non-null childPolicy to the xds_wrr_locality config, typically weighted_target or round_robin.
- If generating config programmatically, assert childPolicy != nil before serializing.
- Validate the JSON against the expected schema (childPolicy is required) before applying via WithServiceConfig.
Example fix
// before
// { "xds_wrr_locality": {} }
// after
// { "xds_wrr_locality": { "childPolicy": [ { "weighted_target": { "targets": {} } } ] } } Defensive patterns
Strategy: validation
Validate before calling
// Validate the wrr_locality config has a child policy before applying.
func validateWrrLocality(raw json.RawMessage) error {
var c struct {
ChildPolicy json.RawMessage `json:"childPolicy"`
}
if err := json.Unmarshal(raw, &c); err != nil { return err }
if len(c.ChildPolicy) == 0 || string(c.ChildPolicy) == "null" {
return errors.New("xds_wrr_locality requires a non-null childPolicy")
}
return nil
} Prevention
- Always pair xds_wrr_locality with a childPolicy (typically weighted_target).
- Lint generated service configs for required fields before applying.
- Keep an example valid config in tests to anchor expectations.
When it happens
Trigger: Providing an xds_wrr_locality service/LB config JSON whose 'childPolicy' (child_policy) field is absent or null, e.g. {"xds_wrr_locality":{}}. The json.Unmarshal succeeds but lbCfg or lbCfg.ChildPolicy is nil.
Common situations: Hand-authoring a service config and forgetting childPolicy; a control plane translating xDS endpoint config that drops the child policy; version mismatch where an older field name is used.
Related errors
- no priority is provided, all priorities are removed
- xds: unable to unmarshal lbconfig: %s, error: %v
- failed to correctly update Outlier Detection config %v
- xds: unable to unmarshal LBconfig: %s, error: %v
- xds_wrr_locality: invalid LBConfig: %s, error: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/d98b592eaa489871.
Report an issue: GitHub.