{"record":{"id":"b2fc36b383af836f","repo":"grpc/grpc-go","slug":"randomsubsetting-json-unmarshal-failed-for-config","errorCode":null,"errorMessage":"randomsubsetting: json.Unmarshal failed for configuration: %s with error: %v","messagePattern":"randomsubsetting: json\\.Unmarshal failed for configuration: (.+?) with error: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/randomsubsetting/randomsubsetting.go","lineNumber":91,"sourceCode":"\tb.logger = prefixLogger(b)\n\tb.logger.Infof(\"Created\")\n\treturn b\n}\n\ntype lbConfig struct {\n\tserviceconfig.LoadBalancingConfig `json:\"-\"`\n\n\tSubsetSize  uint32                         `json:\"subsetSize,omitempty\"`\n\tChildPolicy *iserviceconfig.BalancerConfig `json:\"childPolicy,omitempty\"`\n}\n\nfunc (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {\n\tlbCfg := &lbConfig{}\n\n\t// Ensure that the specified child policy is registered and validates its\n\t// config, if present.\n\tif err := json.Unmarshal(s, lbCfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"randomsubsetting: json.Unmarshal failed for configuration: %s with error: %v\", string(s), err)\n\t}\n\tif lbCfg.SubsetSize == 0 {\n\t\treturn nil, fmt.Errorf(\"randomsubsetting: SubsetSize must be greater than 0\")\n\t}\n\tif lbCfg.ChildPolicy == nil {\n\t\treturn nil, fmt.Errorf(\"randomsubsetting: ChildPolicy must be specified\")\n\t}\n\n\treturn lbCfg, nil\n}\n\nfunc (bb) Name() string {\n\treturn Name\n}\n\ntype subsettingBalancer struct {\n\t*gracefulswitch.Balancer\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/balancer/randomsubsetting/randomsubsetting.go#L73-L109","documentation":"Returned by randomsubsetting.ParseConfig (randomsubsetting.go:85-92) when json.Unmarshal of the raw service-config JSON into lbConfig fails. The %s is the raw JSON string and %v is the encoding/json error. This is the first gate of the A68 random_subsetting policy: the incoming LB config must be valid JSON matching {subsetSize, childPolicy}.","triggerScenarios":"The service config (or xDS ClusterLoadBalancingPolicy) for the random_subsetting_experimental policy provides malformed JSON, wrong types, unknown structure, or a syntactically broken string to ParseConfig. Also triggered if a non-object (e.g. array or number) is passed as the policy config.","commonSituations":"Hand-written service config JSON with a trailing comma, unquoted keys, or a typo in field names. Mismatch between the xDS control plane's random_subsetting config encoding and what the client expects. Passing the config object directly instead of its raw JSON bytes.","solutions":["Inspect the full error string: the %s shows the exact JSON received and %v shows the json line/column of the syntax/type error. Fix that location.","Validate the JSON with a parser (jq or encoding/json) before shipping it in the service config or xDS.","Ensure the structure is an object with numeric subsetSize and an object childPolicy; remove trailing commas and quote all keys.","If sourcing from xDS, check the EDS/CDS resource and the control plane's translation of random_subsetting."],"exampleFix":"// before\n// raw := `{ \"subsetSize\": 10, \"childPolicy\": { \"round_robin\": {} }, }`  // trailing comma -> error\nraw := `{ \"subsetSize\": 10, \"childPolicy\": { \"round_robin\": {} }, }`\n\n// after\nraw := `{ \"subsetSize\": 10, \"childPolicy\": { \"round_robin\": {} } }`","handlingStrategy":"validation","validationCode":"func validateRandomSubsettingJSON(raw []byte) error {\n    var c struct {\n        SubsetSize  uint32            `json:\"subsetSize\"`\n        ChildPolicy json.RawMessage   `json:\"childPolicy\"`\n    }\n    if err := json.Unmarshal(raw, &c); err != nil {\n        return fmt.Errorf(\"invalid random_subsetting JSON: %w\", err)\n    }\n    return nil\n}","typeGuard":"func isRandomSubsettingConfig(v any) bool {\n    m, ok := v.(map[string]any)\n    if !ok {\n        return false\n    }\n    _, hasSize := m[\"subsetSize\"]\n    _, hasChild := m[\"childPolicy\"]\n    return hasSize && hasChild\n}","tryCatchPattern":"// ParseConfig is invoked by grpc when applying the service config; surface the error early.\n// Dial with WithBlock/return-error semantics and inspect the service-config parse result.","preventionTips":["Validate the service-config JSON with encoding/json before deploying.","Keep a golden example config in tests and assert equality after round-trip.","If sourcing from xDS, test the control-plane translation in a staging environment."],"tags":["go","grpc","load-balancing","random-subsetting","config","json"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}