grpc/grpc-go · error

invalid requestHashHeader

Error message

invalid requestHashHeader %q: key must not end with "-bin"

What it means

Returned by ringhash's parseConfig() (balancer/ringhash/config.go:73) when requestHashHeader ends with the suffix '-bin'. Binary headers (-bin suffix) carry raw bytes and cannot be used as a request-hash key because the hash expects a string value. This is enforced after ValidateKey passes.

Solutions

  1. Use a non-binary (ASCII string) metadata header as requestHashHeader — it must not end with '-bin'.
  2. If you need to hash on a binary header, convert it to a base64 ASCII header first.

Example fix

// before: binary header used as hash key — rejected
grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"ring_hash_experimental":{"requestHashHeader":"trace-bin"}}]}`)

// after: use a non-binary ASCII header
grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"ring_hash_experimental":{"requestHashHeader":"trace-id"}}]}`)
Defensive patterns

Strategy: validation

Validate before calling

func rejectBinaryHeader(h string) error {
    if strings.HasSuffix(strings.ToLower(h), "-bin") {
        return errors.New("requestHashHeader must not end with -bin")
    }
    return nil
}

Prevention

When it happens

Trigger: requestHashHeader is a syntactically valid key but ends in '-bin' (e.g. 'my-key-bin'). The check at line 72 (strings.HasSuffix) fires.

Common situations: Operator picks a binary metadata header as the hash source by mistake; an xDS control plane reuses an existing '-bin' header name.

Related errors


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

Appendix: source

Thrown at balancer/ringhash/config.go:73

		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)
		}
	}
	return &cfg, nil
}

View on GitHub (pinned to 0c51461d27)