grpc/grpc-java · error · ResourceInvalidException

Invalid duration in weighted round robin config: " + ex.getM

Error message

Invalid duration in weighted round robin config: " + ex.getMessage()

What it means

A duration field in the weighted round robin (WRR) localities config (e.g. oob_reporting_period or weight_update_period) failed proto-to-JSON duration conversion (Durations.toString / buildWeightedRoundRobinConfig), meaning the control plane sent an invalid duration value. The factory wraps that IllegalArgumentException into a ResourceInvalidException so the xDS resource is rejected.

Source

Thrown at xds/src/main/java/io/grpc/xds/LoadBalancerConfigFactory.java:302

      return buildRingHashConfig(
          ringHash.hasMinimumRingSize() ? ringHash.getMinimumRingSize().getValue() : null,
          ringHash.hasMaximumRingSize() ? ringHash.getMaximumRingSize().getValue() : null);
    }

    private static ImmutableMap<String, ?> convertWeightedRoundRobinConfig(
        ClientSideWeightedRoundRobin wrr) throws ResourceInvalidException {
      try {
        return buildWrrConfig(
            wrr.hasBlackoutPeriod() ? Durations.toString(wrr.getBlackoutPeriod()) : null,
            wrr.hasWeightExpirationPeriod()
                ? Durations.toString(wrr.getWeightExpirationPeriod()) : null,
            wrr.hasOobReportingPeriod() ? Durations.toString(wrr.getOobReportingPeriod()) : null,
            wrr.hasEnableOobLoadReport() ? wrr.getEnableOobLoadReport().getValue() : null,
            wrr.hasWeightUpdatePeriod() ? Durations.toString(wrr.getWeightUpdatePeriod()) : null,
            wrr.hasErrorUtilizationPenalty() ? wrr.getErrorUtilizationPenalty().getValue() : null,
            ImmutableList.copyOf(wrr.getMetricNamesForComputingUtilizationList()));
      } catch (IllegalArgumentException ex) {
        throw new ResourceInvalidException("Invalid duration in weighted round robin config: "
            + ex.getMessage());
      }
    }

    /**
     * Converts a wrr_locality {@link Any} configuration to service config format.
     */
    private static ImmutableMap<String, ?> convertWrrLocalityConfig(WrrLocality wrrLocality,
        int recursionDepth)
        throws ResourceInvalidException, MaxRecursionReachedException {
      return buildWrrLocalityConfig(
          convertToServiceConfig(wrrLocality.getEndpointPickingPolicy(), recursionDepth + 1));
    }

    /**
     * "Converts" a round_robin configuration to service config format.
     */
    private static ImmutableMap<String, ?> convertRoundRobinConfig() {

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Fix the duration fields (oob_reporting_period, weight_update_period) in the WRR localities config on the control plane to valid protobuf Durations (e.g. "10s", "0.5s")
  2. Check the cause message (appended after the colon) to see which exact value was rejected
  3. Validate the config with Envoy's config dump or protoc validation before pushing it via ADS
  4. Remove the optional duration field entirely if a default is acceptable

Example fix

# before (WRR localities config)
oob_reporting_period: "ten seconds"
# after
oob_reporting_period: "10s"
Defensive patterns

Strategy: validation

Validate before calling

// Validate WRR durations are positive before shipping the config:
if (wrr.hasWeightUpdatePeriod()
    && com.google.protobuf.util.Durations.toMillis(wrr.getWeightUpdatePeriod().getValue()) <= 0) {
  throw new IllegalArgumentException("weight_update_period must be > 0");
}

Try / catch

try {
  serviceConfig = convertWeightedRoundRobinConfig(wrr);
} catch (ResourceInvalidException e) {
  // message carries the original IllegalArgumentException text
  logger.warning("Bad WRR config: " + e.getMessage());
  serviceConfig = defaultRoundRobinConfig();
}

Prevention

When it happens

Trigger: convertWeightedRoundRobinConfig calls buildWeightedRoundRobinConfig with the WRR proto's duration fields; any of them being malformed or out of allowed range throws IllegalArgumentException from the duration conversion/builder, which is rethrown with this message.

Common situations: A custom xDS management server emitting a zero/negative or unrepresentable weight_update_period; proto JSON with a missing unit in a duration string; typo'd duration in a WrrLocality config in an Istio/Envoy patch.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


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