alibaba/nacos · error · IllegalStateException

Ambiguous methods mapped for '{request.getRequestURI()}': {{

Error message

Ambiguous methods mapped for '{request.getRequestURI()}': {{bestMatch}, {secondBestMatch}}

What it means

Thrown by the legacy controller-method resolver when two distinct RequestMappingInfo entries match the same request URL with an equal comparator ranking, so the resolver cannot pick one deterministically. This is an IllegalStateException surfaced only on the deprecated legacy resolver path (nacos.core.controller.legacy-resolver-enabled). It indicates a genuine ambiguous mapping conflict.

Source

Thrown at core/src/main/java/com/alibaba/nacos/core/code/ControllerMethodsCache.java:189

        String httpMethod = request.getMethod();
        String urlKey = httpMethod + REQUEST_PATH_SEPARATOR
            + stripContextPath(path, resolveContextPath(request));
        List<RequestMappingInfo> requestMappingInfos = urlLookup.get(urlKey);
        if (CollectionUtils.isEmpty(requestMappingInfos)) {
            return null;
        }
        List<RequestMappingInfo> matchedInfo = findMatchedInfo(requestMappingInfos, request);
        if (CollectionUtils.isEmpty(matchedInfo)) {
            return null;
        }
        RequestMappingInfo bestMatch = matchedInfo.get(0);
        if (matchedInfo.size() > 1) {
            RequestMappingInfoComparator comparator = new RequestMappingInfoComparator();
            matchedInfo.sort(comparator);
            bestMatch = matchedInfo.get(0);
            RequestMappingInfo secondBestMatch = matchedInfo.get(1);
            if (comparator.compare(bestMatch, secondBestMatch) == 0) {
                throw new IllegalStateException(
                    "Ambiguous methods mapped for '" + request.getRequestURI() + "': {" + bestMatch
                        + ", "
                        + secondBestMatch + "}");
            }
        }
        return methods.get(bestMatch);
    }
    
    private String resolveContextPath(HttpServletRequest request) {
        String requestContextPath = request.getContextPath();
        return StringUtils.isEmpty(requestContextPath) ? EnvUtil.getContextPath()
            : requestContextPath;
    }
    
    private String stripContextPath(String path, String contextPath) {
        if (StringUtils.isEmpty(path) || StringUtils.isEmpty(contextPath)) {
            return path;
        }

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Search the codebase for the colliding path shown in the message and make each mapping unique (distinct path, method, or params).
  2. Disable the legacy resolver (-Dnacos.core.controller.legacy-resolver.enabled=false, the default) so Spring's own RequestMappingHandlerMapping enforces unambiguous mappings at startup instead.
  3. If you added a custom controller, rename/move its @RequestMapping path away from Nacos core paths.

Example fix

// before: ambiguous
@RestController
class Foo {
  @GetMapping("/v3/admin/ns/service") void a(){}
}
// (collides with built-in ServiceControllerV3)

// after: unique path
@RestController
class Foo {
  @GetMapping("/v3/admin/ns/service/ext") void a(){}
}
Defensive patterns

Strategy: validation

Validate before calling

RequestMappingInfoComparator cmp = new RequestMappingInfoComparator();
if (matchedInfo.size() > 1 && cmp.compare(matchedInfo.get(0), matchedInfo.get(1)) == 0) {
    // ambiguous: do not call getMethod; report 409 Conflict upstream
}

Try / catch

try {
    controllerMethodsCache.getMethod(request);
} catch (IllegalStateException e) { /* ambiguous mapping */ }

Prevention

When it happens

Trigger: Two @RequestMapping/@GetMapping etc. in different (or the same) controllers register mappings that collide for a given URL+params and compare as equal under RequestMappingInfoComparator. Triggered once a request hits that URL and both survive findMatchedInfo.

Common situations: Adding a new controller endpoint that duplicates an existing URL; a custom plugin/controller accidentally reusing a Nacos built-in path; upgrading Nacos and a new endpoint shadows an old one; mixing v2 and v3 controllers that bind the same path under the same context.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/dabaa44b81d19690. Report an issue: GitHub.