grpc/grpc-java · error · IllegalArgumentException
MatcherTree must have either exact_match_map or…
Error message
MatcherTree must have either exact_match_map or prefix_match_map
What it means
A MatcherTree must specify exactly one of exact_match_map or prefix_match_map; if neither is set, the constructor throws because the tree has no matching strategy. This is the final else branch after checking both oneof fields.
Solutions
- Add either exact_match_map or prefix_match_map with at least one entry.
- Ensure the config was not truncated and the intended map field is inside matcher_tree.
- Check version compatibility: fields supported by the control plane must also be supported here.
Example fix
// before
{"matcher_tree": {"input": {...}}}
// after
{"matcher_tree": {"input": {...}, "exact_match_map": {"map": {"key": {"matcher": {...}}}}}} Defensive patterns
Strategy: validation
Validate before calling
boolean hasMap = treeProto.hasExactMatchMap() || treeProto.hasPrefixMatchMap();
if (!hasMap) {
throw new IllegalArgumentException("MatcherTree needs exact_match_map or prefix_match_map");
} Type guard
boolean hasTreeMatchStrategy(Matcher.MatcherTree proto) {
return proto.hasExactMatchMap() || proto.hasPrefixMatchMap();
} Try / catch
try {
matcherTree = new MatcherTree(proto, onNoMatch, validator);
} catch (IllegalArgumentException e) {
logger.warn("MatcherTree has no match map: " + e.getMessage());
throw new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage()));
} Prevention
- Ensure templates always render one of the two map fields
- Check control-plane fields are supported by this gRPC version before using them
- Add round-trip validation after config generation
When it happens
Trigger: Constructing MatcherTree from a Matcher.MatcherTree proto that has an input (and no custom_match) but neither exact_match_map nor prefix_match_map set.
Common situations: Configs authored against a newer Envoy API that supports other tree arms (e.g. list_match) being loaded by this implementation, or truncated matcher config from the control plane.
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
- AndMatcher must have at least 2 predicates
- HttpAttributesCelMatchInput cannot be used with MatcherTree
- MatcherList must contain at least one FieldMatcher
- MatcherTree does not support custom_match
- MatcherTree exact_match_map must contain at least one entry
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/bfc5d4671c927b66.
Report an issue: GitHub.
Appendix: source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/MatcherTree.java:84
this.exactMatchMap.put(entry.getKey(),
new OnMatch(entry.getValue(), actionValidator));
}
this.prefixTrie = null;
} else if (proto.hasPrefixMatchMap()) {
Matcher.MatcherTree.MatchMap matchMap = proto.getPrefixMatchMap();
if (matchMap.getMapCount() == 0) {
throw new IllegalArgumentException(
"MatcherTree prefix_match_map must contain at least one entry");
}
this.prefixTrie = new PrefixTrie();
for (Map.Entry<String, Matcher.OnMatch> entry :
matchMap.getMapMap().entrySet()) {
this.prefixTrie.insert(entry.getKey(),
new OnMatch(entry.getValue(), actionValidator));
}
this.exactMatchMap = null;
} else {
throw new IllegalArgumentException(
"MatcherTree must have either exact_match_map or prefix_match_map");
}
if (onNoMatchProto != null) {
this.onNoMatch = new OnMatch(onNoMatchProto, actionValidator);
} else {
this.onNoMatch = null;
}
}
@Override
MatchResult match(MatchContext context) {
Object valueObj = input.apply(context);
if (!(valueObj instanceof String)) {
return onNoMatch != null ? onNoMatch.evaluate(context) : MatchResult.noMatch();
}
String value = (String) valueObj;
if (exactMatchMap != null) {View on GitHub (pinned to 64daddc1f3)