grpc/grpc-java · error · ResourceInvalidException

outlier_detection enforcing_success_rate is > 100

Error message

outlier_detection enforcing_success_rate is > 100

What it means

validateOutlierDetection throws this ResourceInvalidException when outlier_detection.enforcing_success_rate is greater than 100. This field is a percentage controlling how strongly success-rate outlier detection ejects hosts, so it must be within [0, 100]. An out-of-range value invalidates the whole Cluster resource.

Solutions

  1. Set enforcing_success_rate to a percentage in [0, 100] (Envoy default is 50).
  2. Convert per-ten-thousand values (e.g. 5000) to percent (50) before sending.
  3. Clamp the value server-side to 0..100 at config generation.
  4. Audit templates for basis-point vs percent mixing.

Example fix

# before (basis points)
outlier_detection:
  enforcing_success_rate: 5000
# after (percent)
outlier_detection:
  enforcing_success_rate: 50
Defensive patterns

Strategy: validation

Validate before calling

boolean validEnforcingSuccessRate(io.envoyproxy.envoy.type.v3.UInt32Value v) {
  return v == null || v.getValue() <= 100;
}

Type guard

boolean isPercent(long v) {
  return v >= 0 && v <= 100;
}

Try / catch

try {
  parseCluster(resource);
} catch (io.grpc.xds.ResourceInvalidException e) {
  if (e.getMessage().contains("enforcing_success_rate")) {
    log.error("enforcing_success_rate must be <= 100 (percent scale)");
  }
  return null;
}

Prevention

When it happens

Trigger: A Cluster resource parsed by parseNonAggregateCluster contains outlier_detection.enforcing_success_rate (a UInt32Value) with a value > 100, e.g. 1000 from a fraction mis-scaled by 1000x.

Common situations: Sending probability-style values (0.0-1.0) scaled incorrectly; user-supplied dashboard input forwarded without clamping; copy-paste errors between percentage and per-ten-thousand (basis-point) fields like enforcing_success_rate_local_host_default in Envoy.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:416

      }
      if (hasNegativeValues(outlierDetection.getMaxEjectionTime())) {
        throw new ResourceInvalidException(
            "outlier_detection max_ejection_time has a negative value");
      }
    }
    if (outlierDetection.hasMaxEjectionPercent()
        && outlierDetection.getMaxEjectionPercent().getValue() > 100) {
      throw new ResourceInvalidException(
          "outlier_detection max_ejection_percent is > 100");
    }
    if (outlierDetection.hasEnforcingSuccessRate()
        && outlierDetection.getEnforcingSuccessRate().getValue() > 100) {
      throw new ResourceInvalidException(
          "outlier_detection enforcing_success_rate is > 100");
    }
    if (outlierDetection.hasFailurePercentageThreshold()
        && outlierDetection.getFailurePercentageThreshold().getValue() > 100) {
      throw new ResourceInvalidException(
          "outlier_detection failure_percentage_threshold is > 100");
    }
    if (outlierDetection.hasEnforcingFailurePercentage()
        && outlierDetection.getEnforcingFailurePercentage().getValue() > 100) {
      throw new ResourceInvalidException(
          "outlier_detection enforcing_failure_percentage is > 100");
    }

    return outlierDetection;
  }

  static boolean hasNegativeValues(Duration duration) {
    return duration.getSeconds() < 0 || duration.getNanos() < 0;
  }

  @VisibleForTesting
  static io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
      validateUpstreamTlsContext(

View on GitHub (pinned to 64daddc1f3)