hs-web/hsweb-framework · warning · MethodNotAllowedException

method_not_allowed

method_not_allowed

Error message

error.method_not_allowed

What it means

WebFlux's MethodNotAllowedException is mapped (note: with @ResponseStatus(NOT_ACCEPTABLE) on the advice, while the ResponseMessage code is method_not_allowed) to the localized 'error.method_not_allowed' message and the supported methods in the result. It means the HTTP verb used on the URL has no matching handler mapping.

Solutions

  1. Use one of the methods listed in the error response result (getSupportedMethods) for that URL.
  2. Check the controller's @RequestMapping/@GetMapping etc. for the path and verbs actually exposed.
  3. Update the client/SDK to the current API version if the route changed.
  4. Fix typos in method names (e.g. Post vs Get) in the calling code.

Example fix

// before
await axios.delete('/api/users'); // no DELETE on collection
// after
await axios.delete(`/api/users/${id}`);
Defensive patterns

Strategy: validation

Validate before calling

const route = { '/api/users': ['GET','POST'], '/api/users/{id}': ['GET','PUT','DELETE'] };
const verbs = route[url] || [];
if (!verbs.includes(method)) {
  console.warn(`${method} not allowed on ${url}; allowed: ${verbs.join(',')}`);
}

Try / catch

try {
  return await client.request({ method, url });
} catch (e) {
  if (e.response && (e.response.status === 405 || e.response.status === 406) && e.response.data.code === 'method_not_allowed') {
    throw new Error(`Use one of: ${e.response.data.result}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Sending PUT to a collection URL that only defines GET/POST, DELETE on an endpoint without a delete handler, or calling a renamed/removed REST route with the old verb.

Common situations: API version drift between client and server; typos in HTTP method constants; REST clients defaulting to GET when posting; framework upgrade where a controller method was removed.

Related errors


AI-assisted analysis of hs-web/hsweb-framework@b2cfc85a57 (2026-09-13). Data as JSON: /api/errors/1ab42fc4345e6395. Report an issue: GitHub.

Appendix: source

Thrown at hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java:259

                .result(e.getSupportedMediaTypes()));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public Mono<ResponseMessage<Object>> handleException(NotAcceptableStatusException e) {
        log.warn(e.getLocalizedMessage(), e);

        return LocaleUtils
            .resolveMessageReactive("error.not_acceptable_media_type")
            .map(msg -> ResponseMessage
                .error(406, "not_acceptable_media_type", msg)
                .result(e.getSupportedMediaTypes()));
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public Mono<ResponseMessage<Object>> handleException(MethodNotAllowedException e) {
        log.warn(e.getLocalizedMessage(), e);

        return LocaleUtils
            .resolveMessageReactive("error.method_not_allowed")
            .map(msg -> ResponseMessage
                .error(406, "method_not_allowed", msg)
                .result(e.getSupportedMethods()));
    }


    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Mono<ResponseMessage<List<ValidationException.Detail>>> handleException(ServerWebInputException e) {
        Throwable exception = e;
        do {
            exception = exception.getCause();
            if (exception instanceof ValidationException) {
                return handleException(((ValidationException) exception));
            }

View on GitHub (pinned to b2cfc85a57)