grpc/grpc-go · error

randomsubsetting: ChildPolicy must be specified

Error message

randomsubsetting: ChildPolicy must be specified

What it means

Returned by randomsubsetting.ParseConfig (randomsubsetting.go:96-98) when ChildPolicy is nil. random_subsetting selects a random subset of endpoints and then delegates connection/picking to a child LB policy, so a child policy (e.g. round_robin) is mandatory. Without it the policy cannot route.

Source

Thrown at balancer/randomsubsetting/randomsubsetting.go:97

	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
	hashDigest *xxhash.Digest
}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Add a childPolicy entry naming a registered LB policy, most commonly round_robin or pick_first.
  2. Confirm the child policy name is spelled exactly as registered (e.g. "round_robin", "pick_first").

Example fix

// before
raw := `{ "subsetSize": 10 }`  // no childPolicy => error

// after
raw := `{ "subsetSize": 10, "childPolicy": { "round_robin": {} } }`
Defensive patterns

Strategy: validation

Validate before calling

func validateChildPolicyPresent(raw []byte) error {
    var c struct{ ChildPolicy json.RawMessage `json:"childPolicy"` }
    _ = json.Unmarshal(raw, &c)
    if len(c.ChildPolicy) == 0 || string(c.ChildPolicy) == "null" {
        return errors.New("childPolicy must be specified")
    }
    return nil
}

Type guard

func hasChildPolicy(c map[string]any) bool {
    cp, ok := c["childPolicy"]
    return ok && cp != nil
}

Prevention

When it happens

Trigger: The config object omits childPolicy, or sets it to null. ParseConfig unmarshals into lbConfig whose ChildPolicy is a pointer, so absence leaves it nil.

Common situations: Treating random_subsetting as a standalone policy rather than a wrapper. Forgetting to nest the underlying policy (round_robin / pick_first) under childPolicy.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/2dc530f60fb7831d. Report an issue: GitHub.