grpc/grpc-java · error · IllegalArgumentException
MatcherList must contain at least one FieldMatcher
Error message
MatcherList must contain at least one FieldMatcher
What it means
A MatcherList must contain at least one FieldMatcher; an empty list can never match anything, so the constructor rejects it eagerly. This enforces the xDS/Envoy matcher API constraint that a list-based matcher defines at least one predicate.
Solutions
- Add at least one FieldMatcher to the MatcherList config.
- Validate on the management server that matchers is non-empty before sending the config.
- If the list may legitimately be empty, restructure to use on_no_match only or drop the matcher entirely.
Example fix
// before
{"matcher_list": {"matchers": []}}
// after
{"matcher_list": {"matchers": [{"predicate": {...}, "on_match": {...}}]}} Defensive patterns
Strategy: validation
Validate before calling
if (proto.getMatchersCount() == 0) {
throw new IllegalArgumentException("MatcherList proto has no matchers; refusing to build");
} Type guard
boolean usableMatcherList(io.envoyproxy.envoy.type.matcher.v3.Matcher.MatcherList proto) {
return proto.getMatchersCount() > 0;
} Try / catch
try {
matcher = new MatcherList(proto, onNoMatch, validator);
} catch (IllegalArgumentException e) {
logger.warn("rejecting empty MatcherList config: " + e.getMessage());
throw new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage()));
} Prevention
- Reject empty matchers arrays at config-generation time
- Require at least one FieldMatcher in templates
- Surface control-plane validation errors instead of emitting empty lists
When it happens
Trigger: Constructing MatcherList from a Matcher.MatcherList proto whose matchers list is empty (matchers_count == 0).
Common situations: Control plane emits a matcher config with an empty matchers array, often after stripping all entries due to a filtering bug or when a template was rendered with no values.
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
- MatcherTree exact_match_map must contain at least one entry
- MatcherTree must have input
- MatcherTree prefix_match_map must contain at least one entry
- OrMatcher must have at least 2 predicates
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/59fb0bc058d39801.
Report an issue: GitHub.
Appendix: source
Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/MatcherList.java:34
package io.grpc.xds.internal.matcher;
import com.github.xds.core.v3.TypedExtensionConfig;
import com.github.xds.type.matcher.v3.Matcher;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import javax.annotation.Nullable;
final class MatcherList extends UnifiedMatcher {
private final List<FieldMatcher> matchers;
@Nullable
private final OnMatch onNoMatch;
MatcherList(Matcher.MatcherList proto, @Nullable Matcher.OnMatch onNoMatchProto,
Predicate<String> actionValidator) {
if (proto.getMatchersCount() == 0) {
throw new IllegalArgumentException("MatcherList must contain at least one FieldMatcher");
}
this.matchers = new ArrayList<>(proto.getMatchersCount());
for (Matcher.MatcherList.FieldMatcher fm : proto.getMatchersList()) {
matchers.add(new FieldMatcher(fm, actionValidator));
}
if (onNoMatchProto != null) {
this.onNoMatch = new OnMatch(onNoMatchProto, actionValidator);
} else {
this.onNoMatch = null;
}
}
@Override
MatchResult match(MatchContext context) {
List<TypedExtensionConfig> accumulated = new ArrayList<>();
for (FieldMatcher matcher : matchers) {
if (matcher.matches(context)) {
MatchResult result = matcher.onMatch.evaluate(context);View on GitHub (pinned to 64daddc1f3)