grpc/grpc-java · error · IllegalArgumentException

Unsupported action type

Error message

Unsupported action type: ${typeUrl}

What it means

When an OnMatch references an action (a TypedExtensionConfig) instead of a nested matcher, the action's type_url must be accepted by the configured actionValidator predicate; otherwise the constructor throws, naming the unsupported typeUrl. This prevents routing actions the surrounding framework (e.g. virtual host / cluster wiring) cannot handle.

Solutions

  1. Use an action typeUrl accepted by the actionValidator passed to the matcher builder (check which actions that context supports).
  2. Update the actionValidator wiring to allow the intended action type if it should be supported.
  3. Replace the action with a nested matcher, or refactor the config so the matcher resolves to a supported action.

Example fix

// before
{"on_match": {"action": {"typed_config": {"@type": ".../Route"}}}}  // validator rejects Route
// after
{"on_match": {"action": {"typed_config": {"@type": ".../ClusterWeight", "name": "c", "weight": 100}}}}
Defensive patterns

Strategy: validation

Validate before calling

String typeUrl = onMatchProto.getAction().getTypedConfig().getTypeUrl();
if (!allowedActionUrls.contains(typeUrl)) {
  throw new IllegalArgumentException("action not allowed in this context: " + typeUrl);
}

Type guard

boolean isSupportedAction(TypedExtensionConfig action, Predicate<String> actionValidator) {
  return actionValidator.test(action.getTypedConfig().getTypeUrl());
}

Try / catch

try {
  onMatch = new OnMatch(proto, actionValidator);
} catch (IllegalArgumentException e) {
  logger.warn("unsupported action in on_match: " + e.getMessage());
  throw new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription(e.getMessage()));
}

Prevention

When it happens

Trigger: Constructing OnMatch from a Matcher.OnMatch proto with hasAction() true whose action.getTypedConfig().getTypeUrl() fails actionValidator.test(typeUrl) — e.g. an action type the matcher was not configured to accept.

Common situations: Route action types like Route or ClusterWeight not registered in the validator when matchers are used in a context that only supports certain actions; new Envoy action types used before support is added.

Related errors


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

Appendix: source

Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/OnMatch.java:42

/**
 * Handles the action to take upon a match (recurse or return action).
 */
final class OnMatch {
  @Nullable private final UnifiedMatcher nestedMatcher;
  @Nullable private final TypedExtensionConfig action;
  final boolean keepMatching;
  
  OnMatch(Matcher.OnMatch proto, Predicate<String> actionValidator) {
    this.keepMatching = proto.getKeepMatching();
    if (proto.hasMatcher()) {
      this.nestedMatcher = UnifiedMatcher.fromProto(proto.getMatcher(), actionValidator);
      this.action = null;
    } else if (proto.hasAction()) {
      this.nestedMatcher = null;
      this.action = proto.getAction();
      String typeUrl = this.action.getTypedConfig().getTypeUrl();
      if (!actionValidator.test(typeUrl)) {
        throw new IllegalArgumentException("Unsupported action type: " + typeUrl);
      }
    } else {
      throw new IllegalArgumentException("OnMatch must have either matcher or action");
    }
  }
  
  MatchResult evaluate(MatchContext context) {
    if (nestedMatcher != null) {
      return nestedMatcher.match(context);
    }
    return MatchResult.create(action);
  }
}

View on GitHub (pinned to 64daddc1f3)