grpc/grpc-java · error · IllegalArgumentException
Unknown path matcher rule type: " + proto.getRuleCase()
Error message
Unknown path matcher rule type: " + proto.getRuleCase()
What it means
An Envoy PathMatcher proto must have its 'rule' oneof set to PATH (with a StringMatcher). parsePathMatcher throws IllegalArgumentException when the oneof is RULE_NOT_SET or an unrecognized new case, because the RBAC url_path matchers cannot be built.
Source
Thrown at xds/src/main/java/io/grpc/xds/RbacFilter.java:312
case URL_PATH:
return parsePathMatcher(principal.getUrlPath());
case METADATA: // hard coded, never match.
return InvertMatcher.create(AlwaysTrueMatcher.INSTANCE);
case IDENTIFIER_NOT_SET:
default:
throw new IllegalArgumentException(
"Unknown principal identifier case: " + principal.getIdentifierCase());
}
}
private static PathMatcher parsePathMatcher(
io.envoyproxy.envoy.type.matcher.v3.PathMatcher proto) {
switch (proto.getRuleCase()) {
case PATH:
return PathMatcher.create(MatcherParser.parseStringMatcher(proto.getPath()));
case RULE_NOT_SET:
default:
throw new IllegalArgumentException(
"Unknown path matcher rule type: " + proto.getRuleCase());
}
}
private static RequestedServerNameMatcher parseRequestedServerNameMatcher(
io.envoyproxy.envoy.type.matcher.v3.StringMatcher proto) {
return RequestedServerNameMatcher.create(MatcherParser.parseStringMatcher(proto));
}
private static AuthHeaderMatcher parseHeaderMatcher(
io.envoyproxy.envoy.config.route.v3.HeaderMatcher proto) {
if (proto.getName().startsWith("grpc-")) {
throw new IllegalArgumentException("Invalid header matcher config: [grpc-] prefixed "
+ "header name is not allowed.");
}
if (":scheme".equals(proto.getName())) {
throw new IllegalArgumentException("Invalid header matcher config: header name [:scheme] "
+ "is not allowed.");View on GitHub (pinned to 64daddc1f3)
Solutions
- Set the path rule explicitly in the url_path matcher, e.g. {path: {prefix: "/api"}}
- Upgrade grpc-xds/envoy protos if a new rule case is being sent
- Replace unsupported path rule types with a supported StringMatcher form (prefix/exact/regex/safe_regex)
- Check the appended rule case in the message to see which case arrived
Example fix
# before
url_path: {}
# after
url_path:
path: {prefix: "/api"} Defensive patterns
Strategy: validation
Validate before calling
if (pathMatcher.getRuleCase() != PathMatcher.RuleCase.PATH) {
throw new IllegalArgumentException("url_path matcher must set a path rule");
} Try / catch
try {
Matcher m = parsePathMatcher(proto);
} catch (IllegalArgumentException e) {
logger.warning("Bad path matcher: " + e.getMessage());
// reject the RBAC config containing it
} Prevention
- Always populate url_path.path with a StringMatcher
- Use standard prefix/exact/regex StringMatcher forms
- Keep envoy-type protos in sync between control plane and client
When it happens
Trigger: parsePermission or parsePrincipal process a Permission/Principal with a url_path field whose PathMatcher proto has no rule set, or contains a rule case added in a newer Envoy API than the client's protos.
Common situations: Hand-written RBAC fixtures omitting the path inside url_path; control plane using newer matcher features (e.g. new path match variants) not present in the client's envoy-type protos; malformed policy JSON from a custom xDS server.
Related errors
- Unknown permission rule case: " + permission.getRuleCase()
- Unknown principal identifier case: " + principal.getIdentifi
- Failed to parse metadata key: %s, type: %s. Error: %s
- Invalid header matcher config: [grpc-] prefixed header name
- Invalid header matcher config: header name [:scheme] is not
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/2ac1dc45efb375bf.
Report an issue: GitHub.