grpc/grpc-java · error · IllegalArgumentException

Unknown denominator type: ${proto.getDenominator()}

Error message

Unknown denominator type: ${proto.getDenominator()}

What it means

FaultFilter.parsePercent converts an Envoy core.FractionalPercent into FaultConfig.FractionalPercent and throws IllegalArgumentException when the denominator enum is not HUNDRED, TEN_THOUSAND, or MILLION — typically because the proto carried UNRECOUGHT/UNRECOGNIZED. The Java enum switch has no mapping for it, so parsing the fault-injection percentage fails.

Source

Thrown at xds/src/main/java/io/grpc/xds/FaultFilter.java:193

              Status.fromCodeValue(faultAbort.getGrpcStatus()), percent));
        case ERRORTYPE_NOT_SET:
        default:
          return ConfigOrError.fromError(
              "Unknown error type case: " + faultAbort.getErrorTypeCase());
      }
    }

    private static FaultConfig.FractionalPercent parsePercent(FractionalPercent proto) {
      switch (proto.getDenominator()) {
        case HUNDRED:
          return FaultConfig.FractionalPercent.perHundred(proto.getNumerator());
        case TEN_THOUSAND:
          return FaultConfig.FractionalPercent.perTenThousand(proto.getNumerator());
        case MILLION:
          return FaultConfig.FractionalPercent.perMillion(proto.getNumerator());
        case UNRECOGNIZED:
        default:
          throw new IllegalArgumentException("Unknown denominator type: " + proto.getDenominator());
      }
    }
  }

  @Nullable
  @Override
  public ClientInterceptor buildClientInterceptor(
      FilterConfig config, @Nullable FilterConfig overrideConfig,
      final ScheduledExecutorService scheduler) {
    checkNotNull(config, "config");
    if (overrideConfig != null) {
      config = overrideConfig;
    }
    FaultConfig faultConfig = (FaultConfig) config;

    final class FaultInjectionInterceptor implements ClientInterceptor {
      @Override
      public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Set the fault config's percent denominator to HUNDRED, TEN_THOUSAND, or MILLION in the LDS response.
  2. Check for control-plane/grpc-java version skew causing unrecognized enum values and align versions.
  3. Inspect the raw LDS proto sent to the client to confirm the denominator value.
  4. If you don't need fractional faults, specify a whole percent with denominator HUNDRED.

Example fix

// before
"percent": { "numerator": 1, "denominator": "UNRECOGNIZED" }
// after
"percent": { "numerator": 100, "denominator": "HUNDRED" }
Defensive patterns

Strategy: validation

Validate before calling

String d = percent.getDenominator().toString();
if (!d.equals("HUNDRED") && !d.equals("TEN_THOUSAND") && !d.equals("MILLION")) {
  throw new IllegalArgumentException("Unsupported denominator: " + d);
}

Try / catch

try { /* build fault config */ } catch (IllegalArgumentException e) { log.error("fault percent invalid: {}", e.getMessage()); }

Prevention

When it happens

Trigger: FaultDelay or FaultConfig percent field whose FractionalPercent.denominator is UNRECOGNIZED (e.g. proto from a newer/older schema) — reached via parsePercent from the percent parser while building fault filter config.

Common situations: Management server sends a fault filter with an unrecognized denominator value due to version skew; corrupted or hand-written LDS fault config.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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