grpc/grpc-java · error · IllegalArgumentException

Unknown permission rule case: " + permission.getRuleCase()

Error message

Unknown permission rule case: " + permission.getRuleCase()

What it means

RBAC permission protos use a oneof 'rule'; parsePermission handles the known cases (and, or, not, any, header, url_path, requested_server_name, etc.). If the rule oneof is unset or a new Envoy case this grpc-xds version doesn't recognize appears, it throws IllegalArgumentException — a hard failure indicating the client cannot build a matcher for that permission.

Source

Thrown at xds/src/main/java/io/grpc/xds/RbacFilter.java:252

      case HEADER:
        return parseHeaderMatcher(permission.getHeader());
      case URL_PATH:
        return parsePathMatcher(permission.getUrlPath());
      case DESTINATION_IP:
        return createDestinationIpMatcher(permission.getDestinationIp());
      case DESTINATION_PORT:
        return createDestinationPortMatcher(permission.getDestinationPort());
      case DESTINATION_PORT_RANGE:
        return parseDestinationPortRangeMatcher(permission.getDestinationPortRange());
      case NOT_RULE:
        return InvertMatcher.create(parsePermission(permission.getNotRule()));
      case METADATA: // hard coded, never match.
        return InvertMatcher.create(AlwaysTrueMatcher.INSTANCE);
      case REQUESTED_SERVER_NAME:
        return parseRequestedServerNameMatcher(permission.getRequestedServerName());
      case RULE_NOT_SET:
      default:
        throw new IllegalArgumentException(
                "Unknown permission rule case: " + permission.getRuleCase());
    }
  }

  private static OrMatcher parsePrincipalList(List<Principal> principals) {
    List<Matcher> anyMatch = new ArrayList<>();
    for (Principal principal: principals) {
      anyMatch.add(parsePrincipal(principal));
    }
    return OrMatcher.create(anyMatch);
  }

  private static Matcher parsePrincipal(Principal principal) {
    switch (principal.getIdentifierCase()) {
      case OR_IDS:
        return parsePrincipalList(principal.getOrIds().getIdsList());
      case AND_IDS:
        List<Matcher> nextMatchers = new ArrayList<>();

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Upgrade io.grpc:grpc-xds (and its envoy-api protos) so the new permission case is supported
  2. Fix the RBAC policy on the control plane so every permission has a set rule
  3. Replace unsupported rule types (e.g. new metadata cases) with combinations of supported matchers
  4. Check the appended rule case value in the message to identify which case is missing

Example fix

# before (permission with no rule)
permissions: {}
# after
permissions:
  - header:
      name: ":path"
      path_match: {path: {prefix: "/svc"}}
Defensive patterns

Strategy: validation

Validate before calling

// Guard before installing an RBAC filter:
if (permission.getRuleCase() == Permission.RuleCase.RULE_NOT_SET) {
  throw new IllegalArgumentException("RBAC permission must have a rule set");
}

Try / catch

try {
  RbacFilter.RbacConfig config = RbacFilter.parseRbacConfig(any);
} catch (IllegalArgumentException e) {
  logger.warning("Unsupported RBAC rule: " + e.getMessage());
  // reject filter config rather than crashing the LB
}

Prevention

When it happens

Trigger: An RBAC filter config in an LDS response contains a Permission whose rule oneof is RULE_NOT_SET or an enum case newer than the loaded envoy-common protos; parsePermission (recursively via parsePermissionList/parsePermission) reaches the default branch.

Common situations: Control plane with a newer Envoy RBAC feature than the gRPC client's protos; RBAC policy with an empty permission block (rule not set); corrupted/partial RBAC config from a custom xDS server.

Related errors


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