grpc/grpc-java · error · IllegalArgumentException
Unknown principal identifier case: " + principal.getIdentifi
Error message
Unknown principal identifier case: " + principal.getIdentifierCase()
What it means
RBAC principal protos use a oneof 'identifier' (and_ids, or_ids, not_id, authenticated, source_ip, header, url_path, metadata, etc.). parsePrincipal throws IllegalArgumentException when the identifier is unset or is a case this client version doesn't implement, since no matcher can be constructed for the principal.
Source
Thrown at xds/src/main/java/io/grpc/xds/RbacFilter.java:300
return createSourceIpMatcher(principal.getRemoteIp());
case SOURCE_IP: {
// gRFC A41 has identical handling of source_ip as remote_ip and direct_remote_ip and
// pre-dates the deprecation.
@SuppressWarnings("deprecation")
CidrRange sourceIp = principal.getSourceIp();
return createSourceIpMatcher(sourceIp);
}
case HEADER:
return parseHeaderMatcher(principal.getHeader());
case NOT_ID:
return InvertMatcher.create(parsePrincipal(principal.getNotId()));
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) {View on GitHub (pinned to 64daddc1f3)
Solutions
- Upgrade grpc-xds dependency to match the control plane's Envoy API version
- Ensure each Principal in the RBAC policy has an identifier set on the control plane
- Rewrite unsupported identifier cases using supported ones (authenticated, source_ip, header, url_path, and/or/not)
- Log/print the offending identifier case from the message to pinpoint the policy entry
Example fix
# before
principals: {}
# after
principals:
- authenticated: {principal_name: {exact: "spiffe://cluster/ns/sa/sa-name"}} Defensive patterns
Strategy: validation
Validate before calling
if (principal.getIdentifierCase() == Principal.IdentifierCase.IDENTIFIER_NOT_SET) {
throw new IllegalArgumentException("RBAC principal must have an identifier");
} Try / catch
try {
Matcher m = parsePrincipal(principal);
} catch (IllegalArgumentException e) {
logger.warning("Unsupported RBAC principal: " + e.getMessage());
// reject the policy; do not default to allow-all
} Prevention
- Always set exactly one identifier on each Principal
- Pin grpc-xds protos to >= control plane Envoy API version
- Validate RBAC policies with Envoy before pushing to gRPC clients
When it happens
Trigger: An RBAC policy's principals list contains a Principal with IDENTIFIER_NOT_SET or a newly added Envoy identifier case unknown to the loaded protos; parsePrincipal recurses through parsePrincipalList and hits the default branch.
Common situations: Envoy control plane newer than gRPC client protos using a new principal identifier; empty principal block in a policy; custom xDS server emitting incomplete RBAC policies.
Related errors
- Unknown permission rule case: " + permission.getRuleCase()
- Unknown path matcher rule type: " + proto.getRuleCase()
- Failed to parse Rbac policy: %s
- Failed to parse metadata key: %s, type: %s. Error: %s
- Invalid header matcher config: [grpc-] prefixed header name
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/d909f34af73c724c.
Report an issue: GitHub.