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
- Use an action typeUrl accepted by the actionValidator passed to the matcher builder (check which actions that context supports).
- Update the actionValidator wiring to allow the intended action type if it should be supported.
- 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
- Keep the set of validator-accepted action typeUrls documented next to matcher wiring
- Before adding new Envoy action types, extend actionValidator
- Prefer nested matchers when the context does not define supported actions
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
- 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/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)