alibaba/nacos · error · IllegalArgumentException
Capturing patterns ({name}) are not supported by the AntPath
Error message
Capturing patterns ({name}) are not supported by the AntPathMatcher. Use the PathPatternParser instead. What it means
AntPathMatcher rejects URI-template variables whose declared name begins with `*` (e.g. `{*path}`). Such a name denotes a greedy catch-all capture in Spring's PathPatternParser, a feature AntPathMatcher deliberately does not implement. The matcher detects the asterisk prefix and aborts rather than emit ambiguous or wrong bindings.
Source
Thrown at common/src/main/java/com/alibaba/nacos/common/packagescan/resource/AntPathMatcher.java:606
* @return {@code true} if the string matches against the pattern, or {@code false} otherwise.
*/
public boolean matchStrings(String str, Map<String, String> uriTemplateVariables) {
if (this.exactMatch) {
return this.caseSensitive ? this.rawPattern.equals(str) : this.rawPattern.equalsIgnoreCase(str);
} else if (this.pattern != null) {
Matcher matcher = this.pattern.matcher(str);
if (matcher.matches()) {
if (uriTemplateVariables != null) {
if (this.variableNames.size() != matcher.groupCount()) {
throw new IllegalArgumentException("The number of capturing groups in the pattern segment "
+ this.pattern + " does not match the number of URI template variables it defines, "
+ "which can occur if capturing groups are used in a URI template regex. "
+ "Use non-capturing groups instead.");
}
for (int i = 1; i <= matcher.groupCount(); i++) {
String name = this.variableNames.get(i - 1);
if (name.startsWith("*")) {
throw new IllegalArgumentException("Capturing patterns (" + name + ") are not "
+ "supported by the AntPathMatcher. Use the PathPatternParser instead.");
}
String value = matcher.group(i);
uriTemplateVariables.put(name, value);
}
}
return true;
}
}
return false;
}
}
/**
* A simple cache for patterns that depend on the configured path separator.
*/
private static class PathSeparatorPatternCache {View on GitHub (pinned to 9b989acdf1)
Solutions
- Remove the `*` prefix from the variable name; use a normal `{var}` and handle multi-segment matching with `/**` suffix instead.
- Switch to PathPatternParser if a catch-all capture variable is genuinely required by your routing logic.
- Audit pattern strings coming from external config/YAML for stray `{*` tokens before they reach the matcher.
Example fix
// before
String pattern = "/files/{*file}"; // catch-all capture, unsupported
// after
String pattern = "/files/**"; // match remainder without capture, supported Defensive patterns
Strategy: validation
Validate before calling
static String rejectCatchAllVar(String pattern) {
int i;
while ((i = pattern.indexOf("{*")) >= 0) {
throw new IllegalArgumentException(
"AntPathMatcher does not support {*var}; fix pattern: " + pattern);
}
return pattern;
} Prevention
- Scan every pattern string for the literal `{*` before registering it with AntPathMatcher.
- Reserve `{*...}` for PathPatternParser configurations only.
- Use `/**` suffix instead of `{*remainder}` for trailing catch-all matching.
When it happens
Trigger: Matching a path against a pattern containing a `{*...}` token while a uriTemplateVariables map is passed in (the extraction branch). The check `name.startsWith("*")` fires on the first such variable encountered during the value-binding loop.
Common situations: Porting a PathPatternParser-style mapping (`/resources/**{*tail}`) into AntPathMatcher configuration. Using `/files/{*file}` to capture a multi-segment remainder. Documentation or examples that mix the two matcher dialects.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/4f0fa375d81f7ed2.
Report an issue: GitHub.