grpc/grpc-go · error

failed to marshal built priority config struct into json: %v

Error message

failed to marshal built priority config struct into json: %v

What it means

After successfully building the priority config Go struct, the CDS balancer marshals it to JSON to pass to the child policy's parser. This error fires when json.Marshal fails on the internally constructed struct. Since the struct is built by gRPC's own code from already-validated data, this error indicates either a programming bug or an impossible state.

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 03255a9237)

Solutions

  1. This is an internal gRPC error — report it as a bug with the grpc-go version and cluster configuration details
  2. Try upgrading to the latest grpc-go patch release to see if the bug has been fixed
  3. Enable GRPC_GO_LOG_SEVERITY=info and capture the full error detail to include in the bug report
  4. As a temporary workaround, simplify the cluster configuration (e.g., remove outlier detection or aggregate clusters) to isolate which config triggers the marshal failure
Defensive patterns

Strategy: fallback

Validate before calling

// No pre-validation possible — this is an internal struct-to-JSON marshal failure
// Indicates a gRPC bug; not preventable by user code

Try / catch

// Report as a bug; monitor for persistence
if conn.GetState() == connectivity.TransientFailure {
    // collect full error details and grpc-go version for bug report
}

Prevention

When it happens

Trigger: Triggered in configbuilder.go when json.Marshal(pc) returns an error after buildPriorityConfig succeeded. The struct is a priority.LBConfig containing internally-constructed cluster_impl and outlier detection configs. json.Marshal can fail on unsupported types, cyclic references, or nil map values with custom marshalers.

Common situations: This should essentially never happen in production — it indicates an internal gRPC bug where the config struct contains a value that cannot be marshaled. Could theoretically occur with an unsupported custom type in a custom build, or a regression in a grpc-go version.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/417ec260b4a98685. Report an issue: GitHub.