grpc/grpc-java · error · IllegalArgumentException
Type mismatch: input
Error message
Type mismatch: input ${input output type} not compatible with matcher ${matcher input type} What it means
The resolved MatchInput produces a value of some Java type (input.outputType()), and the chosen Matcher accepts values of matcher.inputType(). The evaluator enforces their compatibility at construction; when the input's output type is not assignable to the matcher's expected input type it throws this IllegalArgumentException so mismatches fail fast instead of at match time.
Solutions
- Change either the input or the matcher so matcher.inputType() equals input.outputType() (e.g. use an IP-typed custom matcher with an IP-producing input)
- Use a value_match (StringMatcher) with a String-producing input such as header/hostname inputs
- Add a registry-level type compatibility check when registering custom inputs and matchers so bad pairs are rejected with a clearer message
Example fix
// before: header (String) input with IP-typed matcher
SinglePredicate.newBuilder().setInput(headerInput)
.setCustomMatch(ipMatcherExtension).build(); // Type mismatch
// after
SinglePredicate.newBuilder().setInput(headerInput)
.setValueMatch(StringMatcher.newBuilder().setExact("1.2.3.4")).build(); Defensive patterns
Strategy: validation
Validate before calling
MatchInput input = UnifiedMatcher.resolveInput(proto.getInput());
Matcher matcher = /* resolved matcher */;
if (!input.outputType().equals(matcher.inputType())) {
throw new IllegalArgumentException("input/matcher type mismatch");
} Try / catch
try { new PredicateEvaluator.SinglePredicateEvaluator(proto); } catch (IllegalArgumentException e) { log.error("Type mismatch in predicate: " + e.getMessage()); throw new ConfigException(e); } Prevention
- Pair inputs and matchers with matching declared types
- Use StringMatcher only with String-producing inputs
- Type-check custom input/matcher pairs at registration time
When it happens
Trigger: Constructing SinglePredicateEvaluator where the input's outputType() (e.g. an int or IPAddress-producing input) differs from the matcher's inputType() (e.g. String) — e.g. pairing a header-string input with a custom matcher that expects an IP type, or a value_match typed for a different input class.
Common situations: Mixing inputs and matchers from different xDS extensions; copy-pasted predicate blocks where input was swapped but value_match kept; new custom input/matcher plugin pairs whose declared types disagree.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- AndMatcher must have at least 2 predicates
- Invalid message type
- Invalid message type
- OrMatcher must have at least 2 predicates
- Predicate must have one of: single_predicate, or_matcher…
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/b5e237a1ecb21e87.
Report an issue: GitHub.
Appendix: source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/PredicateEvaluator.java:75
Matchers.StringMatcher stringMatcher =
MatcherParser.parseStringMatcher(proto.getValueMatch());
this.matcher = new StringMatcherAdapter(stringMatcher);
} else if (proto.hasCustomMatch()) {
TypedExtensionConfig customConfig = proto.getCustomMatch();
MatcherProvider provider = MatcherRegistry.getDefaultRegistry()
.getMatcherProvider(customConfig.getTypedConfig().getTypeUrl());
if (provider == null) {
throw new IllegalArgumentException("Unsupported custom_match matcher: "
+ customConfig.getTypedConfig().getTypeUrl());
}
this.matcher = provider.getMatcher(customConfig);
} else {
throw new IllegalArgumentException(
"SinglePredicate must have either value_match or custom_match");
}
if (!input.outputType().equals(matcher.inputType())) {
throw new IllegalArgumentException("Type mismatch: input " + input.outputType().getName()
+ " not compatible with matcher " + matcher.inputType().getName());
}
}
@Override
boolean evaluate(MatchContext context) {
return matcher.match(input.apply(context));
}
private static final class StringMatcherAdapter implements Matcher {
private final Matchers.StringMatcher stringMatcher;
StringMatcherAdapter(Matchers.StringMatcher stringMatcher) {
this.stringMatcher = stringMatcher;
}
View on GitHub (pinned to 64daddc1f3)