{"record":{"id":"7e53d2bdd6279d42","repo":"grpc/grpc-java","slug":"unknown-denominator-type-of-percent","errorCode":null,"errorMessage":"Unknown denominator type of ${percent}","messagePattern":"Unknown denominator type of (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsEndpointResource.java","lineNumber":182,"sourceCode":"      io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment.Policy.DropOverload proto) {\n    return DropOverload.create(proto.getCategory(), getRatePerMillion(proto.getDropPercentage()));\n  }\n\n  private static int getRatePerMillion(FractionalPercent percent) {\n    int numerator = percent.getNumerator();\n    FractionalPercent.DenominatorType type = percent.getDenominator();\n    switch (type) {\n      case TEN_THOUSAND:\n        numerator *= 100;\n        break;\n      case HUNDRED:\n        numerator *= 10_000;\n        break;\n      case MILLION:\n        break;\n      case UNRECOGNIZED:\n      default:\n        throw new IllegalArgumentException(\"Unknown denominator type of \" + percent);\n    }\n\n    if (numerator > 1_000_000 || numerator < 0) {\n      numerator = 1_000_000;\n    }\n    return numerator;\n  }\n\n\n  @VisibleForTesting\n  @Nullable\n  static StructOrError<LocalityLbEndpoints> parseLocalityLbEndpoints(\n      io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints proto)\n      throws ResourceInvalidException {\n    // Filter out localities without or with 0 weight.\n    if (!proto.hasLoadBalancingWeight() || proto.getLoadBalancingWeight().getValue() < 1) {\n      return null;\n    }","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsEndpointResource.java#L164-L200","documentation":"When converting a drop_overload percentage into a rate-per-million, getRatePerMillion switches on the FractionalPercent denominator. A UNRECOGNIZED or unset denominator hits the default branch and throws IllegalArgumentException, meaning the EDS resource carried a percent value the proto enum could not resolve.","triggerScenarios":"parseDropOverload passes a ClusterLoadAssignment drop_overload's FractionalPercent whose denominator is UNRECOGNIZED (unknown enum value from a newer/older proto, or zero-value misuse) into getRatePerMillion.","commonSituations":"Control plane built against a different protobuf version emitting an enum value grpc-java cannot resolve; hand-crafted drop_overload configs omitting denominator; proto wire corruption yielding UNRECOGNIZED.","solutions":["Set denominator explicitly to HUNDRED, TEN_THOUSAND, or MILLION on drop_overload percent","Rebuild/align control-plane protos with the grpc-java xDS proto versions","Validate drop_overload percentages before sending EDS updates","Note this surfaces as IllegalArgumentException (internal), typically causing the EDS watch to fail — fix at the config source"],"exampleFix":"# before\ndrop_overloads:\n- category: \"lb\"\n  drop_percentage: { numerator: 5 }   # denominator unset\n# after\ndrop_overloads:\n- category: \"lb\"\n  drop_percentage: { numerator: 5, denominator: HUNDRED }","handlingStrategy":"validation","validationCode":"for (DropOverload d : assignment.getPolicy().getDropOverloadsList()) {\n  if (d.getDropPercentage().getDenominator() == FractionalPercent.DenominatorType.UNRECOGNIZED\n      || d.getDropPercentage().getDenominatorValue() == 0) {\n    throw new IllegalArgumentException(\"drop_percentage denominator unset/unknown\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  update = XdsEndpointResource.getInstance().parse(args, resource);\n} catch (IllegalArgumentException e) {\n  logger.warn(\"Bad drop_overload percent: {}\", e.getMessage());\n}","preventionTips":["Always set denominator (HUNDRED/TEN_THOUSAND/MILLION) on drop percentages","Align proto versions between control plane and grpc-java so enum values resolve","Reject UNRECOGNIZED denominators in control-plane validation"],"tags":["xds","eds","enum","drop-overload","grpc-java"],"backgroundTag":"unsupported-enum-value","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}