grpc/grpc-java · error · IllegalArgumentException
Predicate must have one of: single_predicate, or_matcher, an
Error message
Predicate must have one of: single_predicate, or_matcher, and_matcher, not_matcher
What it means
PredicateEvaluator.fromProto converts a Predicate proto into a runtime evaluator by switching on its match_type oneof. If the oneof is MATCHTYPE_NOT_SET (or hits the default branch), no evaluator can be built, so it throws this IllegalArgumentException.
Source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/PredicateEvaluator.java:41
import java.util.ArrayList;
import java.util.List;
abstract class PredicateEvaluator {
abstract boolean evaluate(MatchContext context);
static PredicateEvaluator fromProto(Predicate proto) {
switch (proto.getMatchTypeCase()) {
case SINGLE_PREDICATE:
return new SinglePredicateEvaluator(proto.getSinglePredicate());
case OR_MATCHER:
return new OrMatcherEvaluator(proto.getOrMatcher());
case AND_MATCHER:
return new AndMatcherEvaluator(proto.getAndMatcher());
case NOT_MATCHER:
return new NotMatcherEvaluator(proto.getNotMatcher());
case MATCHTYPE_NOT_SET:
default:
throw new IllegalArgumentException(
"Predicate must have one of: single_predicate, or_matcher, and_matcher, not_matcher");
}
}
private static final class SinglePredicateEvaluator extends PredicateEvaluator {
private final MatchInput input;
private final Matcher matcher;
SinglePredicateEvaluator(Predicate.SinglePredicate proto) {
if (!proto.hasInput()) {
throw new IllegalArgumentException("SinglePredicate must have input");
}
this.input = UnifiedMatcher.resolveInput(proto.getInput());
if (proto.hasValueMatch()) {
Matchers.StringMatcher stringMatcher =
MatcherParser.parseStringMatcher(proto.getValueMatch());
this.matcher = new StringMatcherAdapter(stringMatcher);View on GitHub (pinned to 64daddc1f3)
Solutions
- Populate one of the oneof fields (single_predicate, or_matcher, and_matcher, not_matcher) on every Predicate in the matcher config
- Fix the upstream management server / config generator so it never emits MatchType-not-set predicates
- Pre-validate each Predicate with proto.getMatchTypeCase() != MATCHTYPE_NOT_SET before invoking fromProto
Example fix
// before
Predicate p = Predicate.newBuilder().build();
// after
Predicate p = Predicate.newBuilder()
.setSinglePredicate(SinglePredicate.newBuilder()
.setInput(input)
.setValueMatch(stringMatcher))
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (predicate.getMatchTypeCase() == Predicate.MatchTypeCase.MATCHTYPE_NOT_SET) {
throw new IllegalArgumentException("Predicate has no match type set");
} Try / catch
try { PredicateEvaluator.fromProto(p); } catch (IllegalArgumentException e) { log.error("Bad predicate: " + e.getMessage()); throw new ConfigException(e); } Prevention
- Set exactly one of single_predicate/or_matcher/and_matcher/not_matcher per Predicate
- Use proto builders that make the oneof explicit
- Lint xDS configs for unset oneofs before deploy
When it happens
Trigger: Calling PredicateEvaluator.fromProto with a Predicate proto whose match_type field was never set — i.e. the proto message exists but none of single_predicate, or_matcher, and_matcher, or not_matcher was populated, such as a Predicate constructed only via builder without calling setSinglePredicate/setOrMatcher/etc.
Common situations: Management servers emitting empty predicate entries; partial config generation where predicate lists contain placeholder messages; proto deserialization from configs that omitted the oneof field entirely.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- SinglePredicate must have input
- SinglePredicate must have either value_match or custom_match
- OrMatcher must have at least 2 predicates
- AndMatcher must have at least 2 predicates
- unsupported ExtAuthz service type: only grpc_service is supp
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/b69073d3a755905a.
Report an issue: GitHub.