grpc/grpc-go · error
failed to marshal built priority config struct into json
Error message
failed to marshal built priority config struct into json: %v
What it means
Returned by buildPriorityConfigJSON (configbuilder.go:103) when json.Marshal(pc) fails on the priority.LBConfig struct that was just built successfully by buildPriorityConfig. The %v is the JSON marshalling error. Since the struct was constructed in-memory from validated types, a marshal failure indicates an internal type issue (e.g., a channel or function field, or a recursive struct). This is an internal invariant violation — the message is defensive.
Solutions
- Check for version consistency across grpc-go packages in go.mod.
- Inspect the wrapped %v — json.Marshal errors typically name the offending field/type.
- If you forked any of the config structs, ensure all fields are JSON-compatible.
- Report as a bug to grpc-go if using unmodified stock packages.
Defensive patterns
Strategy: try-catch
Try / catch
// Internal invariant violation — json.Marshal on an in-memory struct. // Not actionable by user code; indicates version skew or code bug. // Check: go list -m all | grep grpc — all entries should match.
Prevention
- Pin grpc-go to a single consistent version across all dependencies.
- Avoid replace directives for grpc-go internal packages.
- Run 'go mod tidy' after dependency changes.
When it happens
Trigger: buildPriorityConfig returns a valid *priority.LBConfig (line 97), and json.Marshal is called on it (line 101). json.Marshal fails only if the struct contains unmarshallable types or hits a marshaler that errors. The priority.LBConfig and its children (clusterimpl.LBConfig, outlierdetection.LBConfig, internalserviceconfig.BalancerConfig) are all plain data structs with json tags, so marshal failure is unexpected.
Common situations: A code change that introduced an unmarshallable field type into the config struct tree. Version skew where the struct definition and the marshalling expectations diverge. Extremely unlikely in stock grpc-go.
Related errors
- config parser for Outlier Detection returned config with…
- error parsing Outlier Detection config
- error unmarshalling xDS LB Policy
- failed to build child policy config
- failed to build priority config
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/417ec260b4a98685.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/balancer/cdsbalancer/configbuilder.go:103
// ┌────────┐
// │priority│
// └┬──────┬┘
// │ │
// ┌──────────▼─┐ ┌─▼──────────┐
// │cluster_impl│ │cluster_impl│
// └──────┬─────┘ └─────┬──────┘
// │ │
// ┌──────▼─────┐ ┌─────▼──────┐
// │xDSLBPolicy │ │xDSLBPolicy │ (Locality and Endpoint picking layer)
// └────────────┘ └────────────┘
func buildPriorityConfigJSON(priorities []*priorityConfig, xdsLBPolicy *internalserviceconfig.BalancerConfig) ([]byte, []resolver.Endpoint, error) {
pc, endpoints, err := buildPriorityConfig(priorities, xdsLBPolicy)
if err != nil {
return nil, nil, fmt.Errorf("failed to build priority config: %v", err)
}
ret, err := json.Marshal(pc)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal built priority config struct into json: %v", err)
}
return ret, endpoints, nil
}
func buildPriorityConfig(priorities []*priorityConfig, xdsLBPolicy *internalserviceconfig.BalancerConfig) (*priority.LBConfig, []resolver.Endpoint, error) {
var (
retConfig = &priority.LBConfig{Children: make(map[string]*priority.Child)}
retEndpoints []resolver.Endpoint
)
for _, p := range priorities {
clusterUpdate := p.clusterConfig.Cluster
switch clusterUpdate.ClusterType {
case xdsresource.ClusterTypeEDS:
names, configs, endpoints, err := buildClusterImplConfigForEDS(p.childNameGen, p.clusterConfig, xdsLBPolicy)
if err != nil {
return nil, nil, err
}
retConfig.Priorities = append(retConfig.Priorities, names...)View on GitHub (pinned to 0c51461d27)