grpc/grpc-go · error

randomsubsetting: json.Unmarshal failed for configuration: %

Error message

randomsubsetting: json.Unmarshal failed for configuration: %s with error: %v

What it means

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}.

Source

Thrown at balancer/randomsubsetting/randomsubsetting.go:91

	b.logger = prefixLogger(b)
	b.logger.Infof("Created")
	return b
}

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

View on GitHub (pinned to 03255a9237)

Solutions

  1. 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.
  2. Validate the JSON with a parser (jq or encoding/json) before shipping it in the service config or xDS.
  3. Ensure the structure is an object with numeric subsetSize and an object childPolicy; remove trailing commas and quote all keys.
  4. If sourcing from xDS, check the EDS/CDS resource and the control plane's translation of random_subsetting.

Example fix

// before
// raw := `{ "subsetSize": 10, "childPolicy": { "round_robin": {} }, }`  // trailing comma -> error
raw := `{ "subsetSize": 10, "childPolicy": { "round_robin": {} }, }`

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

Strategy: validation

Validate before calling

func validateRandomSubsettingJSON(raw []byte) error {
    var c struct {
        SubsetSize  uint32            `json:"subsetSize"`
        ChildPolicy json.RawMessage   `json:"childPolicy"`
    }
    if err := json.Unmarshal(raw, &c); err != nil {
        return fmt.Errorf("invalid random_subsetting JSON: %w", err)
    }
    return nil
}

Type guard

func isRandomSubsettingConfig(v any) bool {
    m, ok := v.(map[string]any)
    if !ok {
        return false
    }
    _, hasSize := m["subsetSize"]
    _, hasChild := m["childPolicy"]
    return hasSize && hasChild
}

Try / catch

// ParseConfig is invoked by grpc when applying the service config; surface the error early.
// Dial with WithBlock/return-error semantics and inspect the service-config parse result.

Prevention

When it happens

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

Common situations: 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.

Related errors


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