{"record":{"id":"23f76a9165f9786d","repo":"grpc/grpc-go","slug":"failed-to-parse-load-balancing-policy-for-child-q","errorCode":null,"errorMessage":"failed to parse load balancing policy for child %q: %v","messagePattern":"failed to parse load balancing policy for child %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/balancer/clustermanager/clustermanager.go","lineNumber":129,"sourceCode":"\t\t\t// child fail, while RPCs to other children with good configs\n\t\t\t// continue to succeed.\n\t\t\tnewPolicyName, oldPolicyName := childCfg.ChildPolicy.Name, b.children[childName].ChildPolicy.Name\n\t\t\tif newPolicyName != oldPolicyName {\n\t\t\t\tvar err error\n\t\t\t\tvar cfgJSON []byte\n\t\t\t\tcfgJSON, err = childCfg.ChildPolicy.MarshalJSON()\n\t\t\t\tif err != nil {\n\t\t\t\t\tretErr = fmt.Errorf(\"failed to JSON marshal load balancing policy for child %q: %v\", childName, err)\n\t\t\t\t\tb.setErrorPickerForChild(childName, retErr)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// This overwrites lbCfg to be in the format expected by the\n\t\t\t\t// gracefulswitch balancer. So, when this config is pushed to\n\t\t\t\t// the child (below), it will result in a graceful switch to the\n\t\t\t\t// new child policy.\n\t\t\t\tlbCfg, err = balancergroup.ParseConfig(cfgJSON)\n\t\t\t\tif err != nil {\n\t\t\t\t\tretErr = fmt.Errorf(\"failed to parse load balancing policy for child %q: %v\", childName, err)\n\t\t\t\t\tb.setErrorPickerForChild(childName, retErr)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif err := b.bg.UpdateClientConnState(childName, balancer.ClientConnState{\n\t\t\tResolverState: resolver.State{\n\t\t\t\tEndpoints:     endpointsSplit[childName],\n\t\t\t\tServiceConfig: s.ResolverState.ServiceConfig,\n\t\t\t\tAttributes:    s.ResolverState.Attributes,\n\t\t\t},\n\t\t\tBalancerConfig: lbCfg,\n\t\t}); err != nil {\n\t\t\tretErr = fmt.Errorf(\"failed to push new configuration %v to child %q: %v\", childCfg.ChildPolicy.Config, childName, err)\n\t\t\tb.setErrorPickerForChild(childName, retErr)\n\t\t}\n","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/balancer/clustermanager/clustermanager.go#L111-L147","documentation":"The cluster manager parses the JSON-marshaled child policy config using the gracefulswitch balancer's ParseConfig. This error fires when the JSON is not valid for gracefulswitch's expected format, which wraps a single child policy in a specific JSON array structure. This is distinct from a marshal failure — the JSON was produced but doesn't parse correctly in the target format.","triggerScenarios":"Triggered in cluster_manager's UpdateClientConnState when balancergroup.ParseConfig(cfgJSON) fails. cfgJSON was just produced by MarshalJSON on the child policy config, so this indicates the marshaled output doesn't conform to the gracefulswitch parser's expected schema. This typically indicates a version mismatch or a bug in the child policy's MarshalJSON producing incompatible output.","commonSituations":"A grpc-go version where the child policy's MarshalJSON and gracefulswitch's ParseConfig have incompatible expectations; a custom child balancer with a non-standard MarshalJSON; the child policy config struct references types not understood by the gracefulswitch parser; a regression in the balancergroup parser.","solutions":["Verify you are on a consistent grpc-go version across all imports (check go.mod for version mismatches)","Enable GRPC_GO_LOG_SEVERITY=info to see which child and what JSON caused the parse failure","If using custom balancers, ensure their JSON output conforms to the gracefulswitch config format","Upgrade grpc-go — this is likely a version compatibility issue or regression","The error is isolated to the affected child; other children continue operating"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate that marshaled child policy JSON can be parsed by gracefulswitch\n// (relevant for testing; normally xDS handles this internally)\nfunc validateGracefulswitchParse(cfgJSON []byte) error {\n    _, err := gracefulswitch.ParseConfig(cfgJSON)\n    return err\n}","typeGuard":null,"tryCatchPattern":"// This error is isolated to one child; other children continue working\n// The affected child's RPCs will fail while others succeed","preventionTips":["Keep grpc-go versions consistent across all dependencies","Test xDS route configurations with conformance tests","Monitor per-cluster RPC health to detect isolated parse failures","Report persistent parse failures as bugs with grpc-go version details"],"tags":["xds","clustermanager","json","gracefulswitch","child-policy"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}