grpc/grpc-java · error · IllegalArgumentException
Invalid CelMatcher config
Error message
Invalid CelMatcher config
What it means
getMatcher() wraps the whole unpack/validate/compile sequence in a catch-all that rethrows any failure as IllegalArgumentException("Invalid CelMatcher config", e). This is a generic factory-level wrapper: the original cause (unpack failure, missing fields, CEL type errors) is preserved as the cause chain. Any malformed CelMatcher typed_config ends up here.
Source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/CelStateMatcher.java:70
public CelStateMatcher getMatcher(TypedExtensionConfig config) {
try {
com.github.xds.type.matcher.v3.CelMatcher celProto = config.getTypedConfig()
.unpack(com.github.xds.type.matcher.v3.CelMatcher.class);
if (!celProto.hasExprMatch()) {
throw new IllegalArgumentException("CelMatcher must have expr_match");
}
CelExpression expr = celProto.getExprMatch();
if (!expr.hasCelExprChecked()) {
throw new IllegalArgumentException("CelMatcher must have cel_expr_checked");
}
CelAbstractSyntaxTree ast =
CelProtoAbstractSyntaxTree.fromCheckedExpr(
expr.getCelExprChecked()).getAst();
CelMatcher compiled = CelMatcher.compile(ast);
return new CelStateMatcher(compiled);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid CelMatcher config", e);
}
}
@Override
public String typeUrl() {
return TYPE_URL;
}
}
}
View on GitHub (pinned to 64daddc1f3)
Solutions
- Inspect the cause via e.getCause() to find the real problem (unpack error, missing field, or compile type error).
- Verify the TypedExtensionConfig's typeUrl matches TYPE_URL and that the Any payload is a well-formed CelMatcher proto.
- Confirm expr_match.cel_expr_checked is a BOOL-typed checked expression before sending the config.
- Catch IllegalArgumentException around getMatcher() and NACK the config with the root cause logged.
Example fix
// before
try { matcher = factory.getMatcher(config); } catch (Exception e) { e.printStackTrace(); }
// after
try { matcher = factory.getMatcher(config); }
catch (IllegalArgumentException e) {
logger.log(WARNING, "Bad CelMatcher config", e.getCause()); // inspect cause
nackConfig(config, e.getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!TYPE_URL.equals(config.getTypedConfig().getTypeUrl()))
throw new IllegalArgumentException("unexpected typeUrl: " + config.getTypedConfig().getTypeUrl()); Type guard
boolean isCelMatcherConfig(TypedExtensionConfig c) { return TYPE_URL.equals(c.getTypedConfig().getTypeUrl()); } Try / catch
try { return factory.getMatcher(config); }
catch (IllegalArgumentException e) {
logger.log(WARNING, "Invalid CelMatcher config", e.getCause());
nackConfig(config, e.getMessage());
return null;
} Prevention
- Always inspect e.getCause() — the real failure is in the wrapped exception.
- Validate type_url and payload shape before calling getMatcher().
- NACK invalid xDS configs instead of crashing the request path.
- Log the full proto for triage when this wrapper fires.
When it happens
Trigger: Any exception during getMatcher(): typed_config cannot be unpacked to the CelMatcher proto type, expr_match or cel_expr_checked missing, or CelMatcher.compile() rejecting a non-BOOL AST.
Common situations: Wrong type_url / mismatched packed Any payload; older or newer proto schemas on control plane vs data plane; non-boolean CEL expressions; version skew where the client lacks a referenced xDS matcher type.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- CelMatcher must have expr_match
- CelMatcher must have cel_expr_checked
- CEL expression must evaluate to boolean, got:
- Unsupported input type for CEL evaluation:
- CEL expression must evaluate to string, got: ${ast.getResult
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/1886537e9051edd7.
Report an issue: GitHub.