grpc/grpc-java · error · CelEvaluationException
Unsupported input type for CEL evaluation:
Error message
Unsupported input type for CEL evaluation:
What it means
CelMatcher.match() only accepts inputs implementing CelVariableResolver, which supplies the variable bindings during CEL evaluation. Any other object (or null) cannot be resolved into variables, so the call is rejected with CelEvaluationException before the program runs. The message includes the offending class name or 'null'.
Source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/CelMatcher.java:60
// CelValidationException -> inside cel-compiler -> Forbidden in production signatures
if (ast.getResultType() != SimpleType.BOOL) {
throw new IllegalArgumentException(
"CEL expression must evaluate to boolean, got: " + ast.getResultType());
}
CelCommon.checkAllowedReferences(ast);
CelRuntime.Program program = CelCommon.RUNTIME.createProgram(ast);
return new CelMatcher(program);
}
/**
* Evaluates the CEL expression against the input activation.
*/
boolean match(Object input) throws CelEvaluationException {
Object result;
if (input instanceof CelVariableResolver) {
result = program.eval((CelVariableResolver) input);
} else {
throw new CelEvaluationException(
"Unsupported input type for CEL evaluation: "
+ (input == null ? "null" : input.getClass().getName()));
}
if (result instanceof Boolean) {
return (Boolean) result;
}
throw new CelEvaluationException(
"CEL expression must evaluate to boolean, got: " + result.getClass().getName());
}
}
View on GitHub (pinned to 64daddc1f3)
Solutions
- Wrap the evaluation context in a class implementing CelVariableResolver (e.g. a header-map-backed resolver) and pass that to match().
- Null-check the input and build a resolver before calling match().
- Catch CelEvaluationException at the call site and fall back to a non-match / default decision.
Example fix
// before boolean ok = matcher.match(requestHeaders); // Map, unsupported // after boolean ok = matcher.match(new HeaderResolver(requestHeaders)); // implements CelVariableResolver
Defensive patterns
Strategy: type-guard
Validate before calling
if (input == null || !(input instanceof CelVariableResolver)) {
throw new IllegalArgumentException("match() requires a CelVariableResolver");
} Type guard
boolean isEvaluable(Object input) { return input instanceof CelVariableResolver; } Try / catch
try { return matcher.match(resolver); }
catch (CelEvaluationException e) { logger.warn("CEL eval failed", e); return false; } Prevention
- Provide a single adapter class implementing CelVariableResolver for your request context.
- Never pass raw Maps or protos directly to match().
- Add unit tests covering null input behavior.
When it happens
Trigger: Passing null, a raw Map, a proto request object, or any non-CelVariableResolver value to CelMatcher.match(). Test methods celMatcher_unsupportedInputThrows and celMatcher_nullInputThrows exercise both cases.
Common situations: Calling match() directly with a header map instead of wrapping it in a resolver implementation; refactoring code that previously took typed inputs; unit tests probing null handling.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Unsupported input type for CEL evaluation: ${input class nam
- CEL expression must evaluate to boolean, got:
- CelMatcher must have expr_match
- CelMatcher must have cel_expr_checked
- Invalid CelMatcher config
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/cb61d943da49225c.
Report an issue: GitHub.