grpc/grpc-java · error · IllegalArgumentException

MatcherTree must have input

Error message

MatcherTree must have input

What it means

A MatcherTree evaluates values produced by a single input source, so the proto must set the input field; without an input the tree has nothing to match on and the constructor rejects the config. This is an eager validation of the xDS Matcher.MatcherTree requirement that `input` be present.

Solutions

  1. Set the input field (a TypedExtensionConfig such as HttpRequestHeaderMatchInput) on the MatcherTree proto.
  2. Regenerate the config from the control plane ensuring input is populated.
  3. If no input source is needed, use MatcherList instead of MatcherTree.

Example fix

// before
{"matcher_tree": {"exact_match_map": {...}}}
// after
{"matcher_tree": {"input": {"typed_config": {"@type": ".../HttpRequestHeaderMatchInput", "header_name": "x-key"}}, "exact_match_map": {...}}}
Defensive patterns

Strategy: validation

Validate before calling

if (!treeProto.hasInput()) {
  throw new IllegalArgumentException("MatcherTree config missing input; refusing to build");
}

Type guard

boolean hasInput(Matcher.MatcherTree proto) {
  return proto.hasInput();
}

Try / catch

try {
  matcherTree = new MatcherTree(proto, onNoMatch, validator);
} catch (IllegalArgumentException e) {
  logger.warn("invalid MatcherTree config: " + e.getMessage());
  throw new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage()));
}

Prevention

When it happens

Trigger: Constructing MatcherTree from a Matcher.MatcherTree proto where hasInput() is false (the input field was omitted).

Common situations: Hand-written or templated xDS matcher config missing the input block, or control-plane code building a MatcherTree programmatically without calling setInput.

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


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/29e9aa904e44267e. Report an issue: GitHub.

Appendix: source

Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/MatcherTree.java:43

import java.util.Map;
import java.util.function.Predicate;
import javax.annotation.Nullable;

final class MatcherTree extends UnifiedMatcher {
  private static final String TYPE_URL_HTTP_ATTRIBUTES_CEL_INPUT =
      "type.googleapis.com/xds.type.matcher.v3.HttpAttributesCelMatchInput";
  private final MatchInput input;
  @Nullable 
  private final Map<String, OnMatch> exactMatchMap;
  @Nullable 
  private final PrefixTrie prefixTrie;
  @Nullable 
  private final OnMatch onNoMatch;
  
  MatcherTree(Matcher.MatcherTree proto, @Nullable Matcher.OnMatch onNoMatchProto,
      Predicate<String> actionValidator) {
    if (!proto.hasInput()) {
      throw new IllegalArgumentException("MatcherTree must have input");
    }
    if (proto.getInput().getTypedConfig().getTypeUrl()
        .equals(TYPE_URL_HTTP_ATTRIBUTES_CEL_INPUT)) {
      throw new IllegalArgumentException(
          "HttpAttributesCelMatchInput cannot be used with MatcherTree");
    }
    
    if (proto.hasCustomMatch()) {
      throw new IllegalArgumentException("MatcherTree does not support custom_match");
    }
    
    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");

View on GitHub (pinned to 64daddc1f3)