grpc/grpc-go · error

randomsubsetting: SubsetSize must be greater than 0

Error message

randomsubsetting: SubsetSize must be greater than 0

What it means

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.

Solutions

  1. Set subsetSize to a positive integer (e.g. 10) representing how many endpoints each client should connect to.
  2. Choose subsetSize relative to your total endpoint count (commonly the square root of the endpoint count per A68).

Example fix

// before: subsetSize omitted → defaults to 0 → rejected
grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"random_subsetting_experimental":{"childPolicy":[{"round_robin":{}}]}}]}`)

// after: set subsetSize to a positive value
grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"random_subsetting_experimental":{"subsetSize":10,"childPolicy":[{"round_robin":{}}]}}]}`)
Defensive patterns

Strategy: validation

Validate before calling

// Ensure subsetSize is set and positive.
func validateSubsetSize(s uint32) error {
    if s == 0 {
        return errors.New("random_subsetting: subsetSize must be > 0")
    }
    return nil
}

Prevention

When it happens

Trigger: 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.

Common situations: Operator forgets to set subsetSize; a config template uses 0 as a placeholder; an xDS control plane does not populate the field.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/c3bd8678e2dd72e3. Report an issue: GitHub.

Appendix: source

Thrown at balancer/randomsubsetting/randomsubsetting.go:94

}

type lbConfig struct {
	serviceconfig.LoadBalancingConfig `json:"-"`

	SubsetSize  uint32                         `json:"subsetSize,omitempty"`
	ChildPolicy *iserviceconfig.BalancerConfig `json:"childPolicy,omitempty"`
}

func (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
	lbCfg := &lbConfig{}

	// Ensure that the specified child policy is registered and validates its
	// config, if present.
	if err := json.Unmarshal(s, lbCfg); err != nil {
		return nil, fmt.Errorf("randomsubsetting: json.Unmarshal failed for configuration: %s with error: %v", string(s), err)
	}
	if lbCfg.SubsetSize == 0 {
		return nil, fmt.Errorf("randomsubsetting: SubsetSize must be greater than 0")
	}
	if lbCfg.ChildPolicy == nil {
		return nil, fmt.Errorf("randomsubsetting: ChildPolicy must be specified")
	}

	return lbCfg, nil
}

func (bb) Name() string {
	return Name
}

type subsettingBalancer struct {
	*gracefulswitch.Balancer

	logger     *internalgrpclog.PrefixLogger
	cfg        *lbConfig
	hashSeed   uint64

View on GitHub (pinned to 0c51461d27)