grpc/grpc-java · error · IllegalArgumentException
MatcherTree prefix_match_map must contain at least one entry
Error message
MatcherTree prefix_match_map must contain at least one entry
What it means
If a MatcherTree specifies prefix_match_map, the map must contain at least one entry; an empty prefix map gives the tree nothing to match and is rejected at construction. This enforces the non-empty map invariant before building the prefix trie.
Solutions
- Populate prefix_match_map with at least one prefix -> on_match entry.
- Validate the map is non-empty before sending the config from the management server.
- If prefix matching is not needed, remove prefix_match_map and use exact_match_map.
Example fix
// before
{"matcher_tree": {"input": {...}, "prefix_match_map": {"map": {}}}}
// after
{"matcher_tree": {"input": {...}, "prefix_match_map": {"map": {"/api/": {"matcher": {...}}}}}} Defensive patterns
Strategy: validation
Validate before calling
if (treeProto.hasPrefixMatchMap() && treeProto.getPrefixMatchMap().getMapCount() == 0) {
throw new IllegalArgumentException("prefix_match_map present but empty");
} Type guard
boolean hasNonEmptyPrefixMap(Matcher.MatcherTree proto) {
return !proto.hasPrefixMatchMap() || proto.getPrefixMatchMap().getMapCount() > 0;
} Try / catch
try {
matcherTree = new MatcherTree(proto, onNoMatch, validator);
} catch (IllegalArgumentException e) {
logger.warn("empty prefix_match_map in config: " + e.getMessage());
throw e;
} Prevention
- Omit prefix_match_map rather than sending an empty map
- Verify prefix entries survive config filtering
- Lint xDS configs for empty map fields
When it happens
Trigger: Constructing MatcherTree from a proto with hasPrefixMatchMap() true but matchMap.getMapCount() == 0 (map present but empty).
Common situations: Control plane emitting prefix routing config with all entries filtered out, or templated matcher config where prefix entries were not substituted.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- AndMatcher must have at least 2 predicates
- MatcherList must contain at least one FieldMatcher
- MatcherTree exact_match_map must contain at least one entry
- MatcherTree must have input
- OrMatcher must have at least 2 predicates
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/9809ad3036598cc6.
Report an issue: GitHub.
Appendix: source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/MatcherTree.java:73
this.input = UnifiedMatcher.resolveInput(proto.getInput());
if (proto.hasExactMatchMap()) {
Matcher.MatcherTree.MatchMap matchMap = proto.getExactMatchMap();
if (matchMap.getMapCount() == 0) {
throw new IllegalArgumentException(
"MatcherTree exact_match_map must contain at least one entry");
}
this.exactMatchMap = new HashMap<>();
for (Map.Entry<String, Matcher.OnMatch> entry :
matchMap.getMapMap().entrySet()) {
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;
}View on GitHub (pinned to 64daddc1f3)