grpc/grpc-java · error · IllegalArgumentException
CelMatcher must have cel_expr_checked
Error message
CelMatcher must have cel_expr_checked
What it means
After confirming expr_match is present, getMatcher() requires the CelExpression to contain cel_expr_checked — the type-checked AST form produced by cel compile's CheckedExpr. Without it there is no AST to convert via CelProtoAbstractSyntaxTree.fromCheckedExpr, so the config is rejected.
Source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/CelStateMatcher.java:61
}
@Override
public Class<?> inputType() {
return GrpcCelEnvironment.class;
}
static final class Provider implements MatcherProvider {
@Override
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
- Type-check the expression with the CEL compiler and embed the result via setCelExprChecked(CheckedExpr).
- Verify proto.hasCelExprChecked() on the producer side before emitting the config.
- NACK the xDS config at the management layer with an explanation that only checked expressions are supported.
Example fix
// before CelExpression.newBuilder().setCelExpr(parsedExpr).build(); // after CelExpression.newBuilder().setCelExprChecked(checkOutput.getExprChecked()).build();
Defensive patterns
Strategy: validation
Validate before calling
if (!expr.hasCelExprChecked()) {
throw new IllegalArgumentException("cel_expr_checked required; run CEL checker first");
} Type guard
boolean hasCheckedExpr(CelExpression expr) { return expr.hasCelExprChecked(); } Try / catch
try { return factory.getMatcher(config); }
catch (IllegalArgumentException e) { nackConfig(config, "cel_expr_checked missing"); return null; } Prevention
- Always run the CEL checker (compile with type checking) and embed CheckedExpr, never raw parsed exprs.
- Verify hasCelExprChecked() before serializing configs.
- Keep producer and consumer CEL toolchain versions aligned.
When it happens
Trigger: expr_match is set but only holds unchecked/parsed CelExpr (or is empty), so expr.hasCelExprChecked() is false when getMatcher() unpacks the config.
Common situations: Clients sending source text or unchecked expressions instead of running the CEL checker and embedding CheckedExpr; tooling that serializes ParseOutput rather than CheckOutput; partially populated protos from hand-rolled builders.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- CelMatcher must have expr_match
- Invalid CelMatcher config
- 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/c889c8a8a39df624.
Report an issue: GitHub.