grpc/grpc-java · error · IllegalArgumentException

Missing RingHash configuration

Error message

Missing RingHash configuration

What it means

RingHashLoadBalancer.acceptResolvedAddresses casts the load-balancing policy config to RingHashConfig and throws IllegalArgumentException if it is null. The ring hash LB policy cannot build its consistent-hash ring without its configuration (hash function, ring size bounds, request hash header), so a missing config is a hard error.

Source

Thrown at xds/src/main/java/io/grpc/xds/RingHashLoadBalancer.java:106

    syncContext = checkNotNull(helper.getSynchronizationContext(), "syncContext");
    logger = XdsLogger.withLogId(InternalLogId.allocate("ring_hash_lb", helper.getAuthority()));
    logger.log(XdsLogLevel.INFO, "Created");
    this.random = checkNotNull(random, "random");
  }

  @Override
  public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
    logger.log(XdsLogLevel.DEBUG, "Received resolution result: {0}", resolvedAddresses);
    List<EquivalentAddressGroup> addrList = resolvedAddresses.getAddresses();
    Status addressValidityStatus = validateAddrList(addrList);
    if (!addressValidityStatus.isOk()) {
      return addressValidityStatus;
    }

    // Now do the ringhash specific logic with weights and building the ring
    RingHashConfig config = (RingHashConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
    if (config == null) {
      throw new IllegalArgumentException("Missing RingHash configuration");
    }
    requestHashHeaderKey =
        config.requestHashHeader.isEmpty()
            ? null
            : Metadata.Key.of(config.requestHashHeader, Metadata.ASCII_STRING_MARSHALLER);
    Map<EquivalentAddressGroup, Long> serverWeights = new HashMap<>();
    long totalWeight = 0L;
    for (EquivalentAddressGroup eag : addrList) {
      Long weight = eag.getAttributes().get(XdsAttributes.ATTR_SERVER_WEIGHT);
      // Support two ways of server weighing: either multiple instances of the same address
      // or each address contains a per-address weight attribute. If a weight is not provided,
      // each occurrence of the address will be counted a weight value of one.
      if (weight == null) {
        weight = 1L;
      }
      totalWeight += weight;
      EquivalentAddressGroup addrKey = stripAttrs(eag);
      if (serverWeights.containsKey(addrKey)) {

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Ensure the xDS cluster's ring_hash lb policy carries a valid configuration in the management server config
  2. Check that the grpc-xds version supports the ring_hash fields sent by the control plane and upgrade if needed
  3. When using ring_hash directly, always pass a RingHashConfig (even a default new RingHashConfig()) as the LB policy config

Example fix

// before
nameResolver.ResolutionResult result = resultBuilder.setLoadBalancingPolicyConfig(null).build();
// after
nameResolver.ResolutionResult result = resultBuilder
    .setLoadBalancingPolicyConfig(new RingHashLoadBalancer.RingHashConfig()).build();
Defensive patterns

Strategy: try-catch

Validate before calling

if (lbConfig instanceof RingHashLoadBalancer.RingHashConfig) { /* proceed */ } else { /* supply default config */ }

Type guard

boolean hasRingHashConfig(Object cfg) {
  return cfg instanceof RingHashLoadBalancer.RingHashConfig;
}

Try / catch

try {
  helper.createSubchannel(...);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("Missing RingHash configuration")) {
    // re-select LB with an explicit RingHashConfig
  }
}

Prevention

When it happens

Trigger: The control plane sends a cluster whose lbPolicy is ring_hash but the parsed lb policy config is absent, or an API user calls Helper.createSubchannel/switch to ring_hash without supplying a RingHashConfig via LoadBalancer.Registry.

Common situations: Envoy/xDS cluster configs where the ring_hash policy omits required config fields; custom balancer wiring that selects ring_hash without setting the policy config; version mismatches where the config parser silently yields null.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/ba266deb70f08be3. Report an issue: GitHub.