grpc/grpc-go · error
xds_wrr_locality: error marshalling prepared config: %v
Error message
xds_wrr_locality: error marshalling prepared config: %v
What it means
Returned when json.Marshal of the internally-built weightedtarget.LBConfig fails inside UpdateClientConnState. The source comment marks this 'Shouldn't happen' because the struct is composed of plain maps and uint32 weights that are always marshalable. It is a defensive guard against an unreachable condition.
Source
Thrown at internal/xds/balancer/wrrlocality/balancer.go:178
weightedTargets := make(map[string]weightedtarget.Target)
for _, ep := range s.ResolverState.Endpoints {
// This get of LocalityID could potentially return a zero value. This
// shouldn't happen though (this attribute that is set actually gets
// used to build localities in the first place), and thus don't error
// out, and just build a weighted target with undefined behavior.
locality := xdsinternal.LocalityString(xdsinternal.LocalityIDFromEndpoint(ep))
ai, ok := getAddrInfo(ep)
if !ok {
return fmt.Errorf("xds_wrr_locality: missing locality weight information in endpoint %q", ep)
}
weightedTargets[locality] = weightedtarget.Target{Weight: ai.LocalityWeight, ChildPolicy: lbCfg.ChildPolicy}
}
wtCfg := &weightedtarget.LBConfig{Targets: weightedTargets}
wtCfgJSON, err := json.Marshal(wtCfg)
if err != nil {
// Shouldn't happen.
return fmt.Errorf("xds_wrr_locality: error marshalling prepared config: %v", wtCfg)
}
var sc serviceconfig.LoadBalancingConfig
if sc, err = b.childParser.ParseConfig(wtCfgJSON); err != nil {
return fmt.Errorf("xds_wrr_locality: config generated %v is invalid: %v", wtCfgJSON, err)
}
return b.child.UpdateClientConnState(balancer.ClientConnState{
ResolverState: s.ResolverState,
BalancerConfig: sc,
})
}
func (b *wrrLocalityBalancer) ResolverError(err error) {
b.child.ResolverError(err)
}
func (b *wrrLocalityBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
b.logger.Errorf("UpdateSubConnState(%v, %+v) called unexpectedly", sc, state)View on GitHub (pinned to 0c51461d27)
Solutions
- Treat occurrence as a gRPC bug: capture the wtCfg value (printed in the error) and file an issue with the grpc-go maintainers.
- Verify you are running an unmodified grpc-go release (no local patches to weightedtarget.LBConfig).
- Upgrade to the latest grpc-go patch release in case it was a transient regression.
Defensive patterns
Strategy: try-catch
Try / catch
// Treat as an unrecoverable internal error; do not retry identical input.
if err := b.UpdateClientConnState(s); err != nil && strings.Contains(err.Error(), "error marshalling prepared config") {
// Capture the printed wtCfg and report upstream; fall back to a different LB policy.
} Prevention
- Run an unmodified grpc-go release.
- If this fires, capture the wtCfg value from the error and file a grpc-go bug.
- Keep dependencies locked to known-good grpc-go versions.
When it happens
Trigger: Reached at balancer.go:178 only if json.Marshal(wtCfg) errors. With weightedtarget.LBConfig containing map[string]Target and uint32 weights, standard encoding/json cannot fail in normal operation.
Common situations: Effectively unreachable. Could surface only under memory corruption, a nil map oddity in a patched/forked gRPC, or a future struct change introducing a non-marshalable field.
Related errors
- xds_wrr_locality: invalid LBConfig: %s, error: %v
- xds_wrr_locality: missing locality weight information in end
- xds_wrr_locality: config generated %v is invalid: %v
- last resolver error: %v
- unexpected balancer config with type: %T
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/5c0a1dadf50b3259.
Report an issue: GitHub.