grpc/grpc-go · error
min %v is greater than max %v
Error message
min %v is greater than max %v
What it means
Returned by ringhash.parseConfig (config.go:54-56) when, after applying defaults (min->1024, max->4096 when zero) and the upper-bound clamp, MinRingSize ends up greater than MaxRingSize. The ring requires min <= max so that the actual ring size is chosen uniformly in [min,max]. The %v values are the final min and max.
Source
Thrown at balancer/ringhash/config.go:55
func parseConfig(c json.RawMessage) (*iringhash.LBConfig, error) {
var cfg iringhash.LBConfig
if err := json.Unmarshal(c, &cfg); err != nil {
return nil, err
}
if cfg.MinRingSize > ringHashSizeUpperBound {
return nil, fmt.Errorf("min_ring_size value of %d is greater than max supported value %d for this field", cfg.MinRingSize, ringHashSizeUpperBound)
}
if cfg.MaxRingSize > ringHashSizeUpperBound {
return nil, fmt.Errorf("max_ring_size value of %d is greater than max supported value %d for this field", cfg.MaxRingSize, ringHashSizeUpperBound)
}
if cfg.MinRingSize == 0 {
cfg.MinRingSize = defaultMinSize
}
if cfg.MaxRingSize == 0 {
cfg.MaxRingSize = defaultMaxSize
}
if cfg.MinRingSize > cfg.MaxRingSize {
return nil, fmt.Errorf("min %v is greater than max %v", cfg.MinRingSize, cfg.MaxRingSize)
}
if cfg.MinRingSize > envconfig.RingHashCap {
cfg.MinRingSize = envconfig.RingHashCap
}
if cfg.MaxRingSize > envconfig.RingHashCap {
cfg.MaxRingSize = envconfig.RingHashCap
}
if !envconfig.RingHashSetRequestHashKey {
cfg.RequestHashHeader = ""
}
if cfg.RequestHashHeader != "" {
cfg.RequestHashHeader = strings.ToLower(cfg.RequestHashHeader)
// See rules in https://github.com/grpc/proposal/blob/master/A76-ring-hash-improvements.md#explicitly-setting-the-request-hash-key
if err := metadata.ValidateKey(cfg.RequestHashHeader); err != nil {
return nil, fmt.Errorf("invalid requestHashHeader %q: %v", cfg.RequestHashHeader, err)
}
if strings.HasSuffix(cfg.RequestHashHeader, "-bin") {
return nil, fmt.Errorf("invalid requestHashHeader %q: key must not end with \"-bin\"", cfg.RequestHashHeader)View on GitHub (pinned to 03255a9237)
Solutions
- Ensure minRingSize <= maxRingSize in the config.
- Prefer relying on defaults (omit both) unless you have a measured reason to tune them.
- If from xDS, fix minimumRingSize/maximumRingSize ordering in the Cluster resource.
Example fix
// before
raw := `{"minRingSize": 8192, "maxRingSize": 4096}` // min > max -> error
// after
raw := `{"minRingSize": 2048, "maxRingSize": 8192}` Defensive patterns
Strategy: validation
Validate before calling
func validateRingSizeOrder(raw []byte) error {
var c struct{ MinRingSize, MaxRingSize uint64 `json:"minRingSize"` } // illustrative
var full struct {
MinRingSize uint64 `json:"minRingSize"`
MaxRingSize uint64 `json:"maxRingSize"`
}
_ = json.Unmarshal(raw, &full)
if full.MinRingSize != 0 && full.MaxRingSize != 0 && full.MinRingSize > full.MaxRingSize {
return fmt.Errorf("min %d > max %d", full.MinRingSize, full.MaxRingSize)
}
return nil
} Prevention
- When setting both, always set min <= max.
- Prefer omitting both and using defaults unless tuning is measured.
- Add a config-builder test asserting min<=max.
When it happens
Trigger: Config explicitly sets minRingSize larger than maxRingSize (e.g. min=8192, max=4096). Note: leaving both zero is fine because defaults satisfy min<=max; this only fires when an explicit inversion exists.
Common situations: Swapping the two fields when hand-writing config. xDS control plane emitting inverted min/max. Defaults masking part of the problem (only the explicit inversion triggers it).
Related errors
- min_ring_size value of %d is greater than max supported valu
- max_ring_size value of %d is greater than max supported valu
- invalid requestHashHeader %q: %v
- invalid requestHashHeader %q, key must not end with "-bin"
- randomsubsetting: json.Unmarshal failed for configuration: %
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/61d89c82116e4cc2.
Report an issue: GitHub.