{"record":{"id":"3a86c597811714b4","repo":"grpc/grpc-go","slug":"least-request-lbconfig-choicecount-v-must-be","errorCode":null,"errorMessage":"least-request: lbConfig.choiceCount: %v, must be >= 2","messagePattern":"least-request: lbConfig\\.choiceCount: (.+?), must be >= 2","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/leastrequest/leastrequest.go","lineNumber":73,"sourceCode":"\n\t// ChoiceCount is the number of random SubConns to sample to find the one\n\t// with the fewest outstanding requests. If unset, defaults to 2. If set to\n\t// < 2, the config will be rejected, and if set to > 10, will become 10.\n\tChoiceCount uint32 `json:\"choiceCount,omitempty\"`\n}\n\ntype bb struct{}\n\nfunc (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {\n\tlbConfig := &LBConfig{\n\t\tChoiceCount: 2,\n\t}\n\tif err := json.Unmarshal(s, lbConfig); err != nil {\n\t\treturn nil, fmt.Errorf(\"least-request: unable to unmarshal LBConfig: %v\", err)\n\t}\n\t// \"If `choice_count < 2`, the config will be rejected.\" - A48\n\tif lbConfig.ChoiceCount < 2 { // sweet\n\t\treturn nil, fmt.Errorf(\"least-request: lbConfig.choiceCount: %v, must be >= 2\", lbConfig.ChoiceCount)\n\t}\n\t// \"If a LeastRequestLoadBalancingConfig with a choice_count > 10 is\n\t// received, the least_request_experimental policy will set choice_count =\n\t// 10.\" - A48\n\tif lbConfig.ChoiceCount > 10 {\n\t\tlbConfig.ChoiceCount = 10\n\t}\n\treturn lbConfig, nil\n}\n\nfunc (bb) Name() string {\n\treturn Name\n}\n\nfunc (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) balancer.Balancer {\n\tb := &leastRequestBalancer{\n\t\tClientConn:        cc,\n\t\tendpointRPCCounts: resolver.NewEndpointMap[*atomic.Int32](),","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/balancer/leastrequest/leastrequest.go#L55-L91","documentation":"Returned by least_request_experimental's ParseConfig() (balancer/leastrequest/leastrequest.go:73). Per gRFC A48, choiceCount must be >= 2. When unset, the code defaults it to 2 (line 66), so this error only fires when choiceCount is explicitly set to 0 or 1. Values > 10 are silently clamped to 10, but values < 2 are rejected outright.","triggerScenarios":"The least_request_experimental config JSON explicitly sets choiceCount to 0 or 1, hitting the check at line 72 (lbConfig.ChoiceCount < 2). ParseConfig returns this error, failing service config application.","commonSituations":"Operator misconfigures choiceCount thinking lower means less overhead; a config template uses 0 meaning 'default' (but 0 is rejected, not defaulted — only omitted is defaulted); xDS control plane pushes an out-of-range value.","solutions":["Set choiceCount to a value between 2 and 10, or omit it entirely to use the default of 2.","If you want the fewest samples, use exactly 2.","Add a config validator that rejects choiceCount < 2 before deployment."],"exampleFix":"// before: explicitly sets choiceCount to 1 — rejected\ngrpc.WithDefaultServiceConfig(`{\"loadBalancingConfig\":[{\"least_request_experimental\":{\"choiceCount\":1}}]}`)\n\n// after: omit choiceCount (defaults to 2) or set it to >= 2\ngrpc.WithDefaultServiceConfig(`{\"loadBalancingConfig\":[{\"least_request_experimental\":{\"choiceCount\":2}}]}`)","handlingStrategy":"validation","validationCode":"// Reject choiceCount < 2 before sending the config.\nfunc validateChoiceCount(c uint32) error {\n    if c < 2 {\n        return fmt.Errorf(\"choiceCount %d must be >= 2\", c)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Document that choiceCount is optional and defaults to 2 — do not pass 0 meaning 'default'.","Add a config schema check (e.g. in an xDS policy validator) for 2 <= choiceCount <= 10."],"tags":["grpc","balancer","least-request","config","validation","choice-count"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}