alibaba/nacos · critical · NacosRuntimeException

500

500

Error message

Spring MVC RequestMappingHandlerMapping is unavailable

What it means

Thrown inside ControllerMethodsCache.getMethodFromHandlerMapping when neither the web application context (servlet context) nor the injected ObjectProvider<RequestMappingHandlerMapping> can supply a RequestMappingHandlerMapping bean. This bean is the core Spring MVC component that resolves @RequestMapping handlers, so its absence means the request cannot be dispatched/matched for authorization purposes. It surfaces as a 500 NacosRuntimeException.

Source

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

    public Method getMethod(HttpServletRequest request) {
        if (handlerMappingProvider != null && !isLegacyResolverEnabled()) {
            return getMethodFromHandlerMapping(request);
        }
        return getMethodFromLegacyCache(request);
    }
    
    private boolean isLegacyResolverEnabled() {
        String systemProperty = System.getProperty(LEGACY_RESOLVER_ENABLED);
        if (systemProperty != null) {
            return Boolean.parseBoolean(systemProperty);
        }
        return EnvUtil.getProperty(LEGACY_RESOLVER_ENABLED, Boolean.class, false);
    }
    
    private Method getMethodFromHandlerMapping(HttpServletRequest request) {
        RequestMappingHandlerMapping handlerMapping = resolveHandlerMapping(request);
        if (handlerMapping == null) {
            throw new NacosRuntimeException(NacosException.SERVER_ERROR,
                "Spring MVC RequestMappingHandlerMapping is unavailable");
        }
        boolean parsedRequestPath = false;
        try {
            if (handlerMapping.usesPathPatterns()
                && !ServletRequestPathUtils.hasParsedRequestPath(request)) {
                ServletRequestPathUtils.parseAndCache(request);
                parsedRequestPath = true;
            }
            HandlerExecutionChain handler = handlerMapping.getHandler(request);
            if (handler == null || !(handler.getHandler() instanceof HandlerMethod)) {
                return null;
            }
            return ((HandlerMethod) handler.getHandler()).getMethod();
        } catch (Exception e) {
            throw new NacosRuntimeException(NacosException.SERVER_ERROR,
                "Failed to resolve Spring MVC controller method", e);
        } finally {

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Ensure the Nacos server boots through the standard Spring Boot web autoconfiguration so the 'requestMappingHandlerMapping' bean is created.
  2. If testing, attach a real WebApplicationContext to the mock servlet context (MockMvc / WebApplicationContextUtils.setupRequestContext) before invoking the filter.
  3. Verify no custom @EnableWebMvc or excluded autoconfiguration removed the handler mapping bean.
  4. As a temporary workaround, force the legacy resolver with -Dnacos.core.controller.legacy-resolver-enabled=true (deprecated, removed in 3.4.0).

Example fix

// before: mock request without app context
MockHttpServletRequest req = new MockHttpServletRequest("GET", "/v3/admin/ns/service");

// after: bind the web app context so the handler mapping bean is resolvable
WebApplicationContextUtils.setupRequestContext(
    (WebApplicationContext) springContext,
    mockServletContext, req, null);
Defensive patterns

Strategy: validation

Validate before calling

RequestMappingHandlerMapping mapping = webApplicationContext != null
    && webApplicationContext.containsBean("requestMappingHandlerMapping")
    ? webApplicationContext.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class)
    : handlerMappingProvider.getIfUnique();
if (mapping == null) {
    // do not proceed; the MVC stack is not initialized
}

Try / catch

try {
    Method m = controllerMethodsCache.getMethod(request);
} catch (NacosRuntimeException e) {
    if (e.getErrCode() == NacosException.SERVER_ERROR
        && e.getMessage().contains("RequestMappingHandlerMapping is unavailable")) {
        // infra misconfiguration — fail fast with a clear 503
    }
}

Prevention

When it happens

Trigger: Occurs when the Spring WebApplicationContext attached to the request is null, when it lacks the 'requestMappingHandlerMapping' bean, AND the handlerMappingProvider has no unique candidate. Typically seen in embedded/custom servlet configurations, unit/integration tests that mock the servlet context, or a broken/fragmented Spring context where MVC autoconfiguration did not run.

Common situations: Running Nacos filter chains outside a fully-bootstrapped Spring MVC stack; a test harness that injects a mock HttpServletRequest without a real ServletContext/ApplicationContext; upgrading Spring Boot where the RequestMappingHandlerMapping bean name changed; a custom context that disables WebMvcAutoConfiguration.

Related errors


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