{"record":{"id":"c3bd8678e2dd72e3","repo":"grpc/grpc-go","slug":"randomsubsetting-subsetsize-must-be-greater-than","errorCode":null,"errorMessage":"randomsubsetting: SubsetSize must be greater than 0","messagePattern":"randomsubsetting: SubsetSize must be greater than 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/randomsubsetting/randomsubsetting.go","lineNumber":94,"sourceCode":"}\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\n\tlogger     *internalgrpclog.PrefixLogger\n\tcfg        *lbConfig\n\thashSeed   uint64","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/balancer/randomsubsetting/randomsubsetting.go#L76-L112","documentation":"Returned by random_subsetting_experimental's ParseConfig() (balancer/randomsubsetting/randomsubsetting.go:94). The lbConfig struct uses a uint32 SubsetSize with omitempty, so an unset/zero value unmarshals to 0. Per the check at line 93, a zero SubsetSize is rejected because subsetting to zero endpoints is meaningless.","triggerScenarios":"The random_subsetting_experimental config omits subsetSize entirely, or explicitly sets it to 0. json.Unmarshal succeeds but SubsetSize == 0, hitting the check at line 93.","commonSituations":"Operator forgets to set subsetSize; a config template uses 0 as a placeholder; an xDS control plane does not populate the field.","solutions":["Set subsetSize to a positive integer (e.g. 10) representing how many endpoints each client should connect to.","Choose subsetSize relative to your total endpoint count (commonly the square root of the endpoint count per A68)."],"exampleFix":"// before: subsetSize omitted → defaults to 0 → rejected\ngrpc.WithDefaultServiceConfig(`{\"loadBalancingConfig\":[{\"random_subsetting_experimental\":{\"childPolicy\":[{\"round_robin\":{}}]}}]}`)\n\n// after: set subsetSize to a positive value\ngrpc.WithDefaultServiceConfig(`{\"loadBalancingConfig\":[{\"random_subsetting_experimental\":{\"subsetSize\":10,\"childPolicy\":[{\"round_robin\":{}}]}}]}`)","handlingStrategy":"validation","validationCode":"// Ensure subsetSize is set and positive.\nfunc validateSubsetSize(s uint32) error {\n    if s == 0 {\n        return errors.New(\"random_subsetting: subsetSize must be > 0\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set subsetSize explicitly in random_subsetting configs.","Pick subsetSize relative to total endpoints (A68 suggests ~sqrt(N))."],"tags":["grpc","balancer","random-subsetting","config","validation","subset-size"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}