405 Method Not Allowed: причины и решения
405 Method Not Allowed означает, что ресурс существует, и сервер понял запрос, но не принимает HTTP-метод, которым вы к нему обратились. На страницу, доступную только через GET, нельзя отправить POST, а на эндпоинт формы, построенный под POST, нельзя обратиться через PUT, и сервер отказывает именно на этом основании.
Что означает 405 Method Not Allowed
RFC 9110 требует, чтобы ответ 405 включал заголовок Allow, перечисляющий методы, которые ресурс реально поддерживает. Этот заголовок - вся диагностика в одной строке: если запрос к /api/users возвращает 405 с Allow: GET, HEAD, маршрут существует и прекрасно работает для чтения, у него просто никогда не было подключено обработчика для того метода, который вы отправили.
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
Как проявляется ошибка
Браузеры показывают общую страницу ошибки для 405, возвращенного на обычную навигацию, поскольку это не тот случай, для которого у них есть специальная обработка. Гораздо чаще с 405 сталкиваются на вкладке сети, в провалившемся AJAX-вызове либо в провале CORS-preflight в консоли, поскольку большинство 405 приходят от скриптовых запросов, а не от кликнутых ссылок. Из командной строки метод и заголовок Allow рассказывают всю историю:
curl -i -X POST https://example.com/downloads/report.pdf
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
Что вызывает 405 Method Not Allowed
- Отправка POST на статический файл. Запрос к реальному файлу на диске, такому как PDF или изображение, отдаваемому веб-сервером, который для статического содержимого отвечает только на GET и HEAD.
- Обращение к маршруту, определяющему только некоторые методы. Маршрут фреймворка, зарегистрированный только для GET, по замыслу возвращает 405 для любого другого метода, а не 404.
- Отклоненный CORS-preflight-запрос OPTIONS. Браузеры автоматически отправляют запрос
OPTIONSперед некоторыми межисточниковыми вызовами, и сервер или шлюз без обработчика OPTIONS на этом пути отвечает 405, что затем проявляется в браузере как заблокированный межисточниковый запрос, а не как явный 405. - nginx, обслуживающий блок location, предназначенный для статических файлов. Блок
location, использующийtry_filesк файловой системе без proxy_pass, даст 405 на POST, поскольку обслуживание статических файлов в nginx реализует только GET, HEAD и по умолчанию ограниченный набор методов. - Ограничения методов у WebDAV и IIS. IIS и некоторые серверы с поддержкой WebDAV явно задают белый список методов по пути, и метод за пределами этого списка, включая пользовательские вроде PROPFIND, получает 405, даже если общий маршрут в остальном работает.
- Неправильная настройка маршрута фреймворка. Маршрут, задуманный принимать и GET, и POST, но зарегистрированный только для одного, часто после рефакторинга, разделившего обработчик без обновления объявления маршрута.
- Белый список методов у балансировщика нагрузки или API-шлюза. Некоторые шлюзы ограничивают разрешенные методы по маршруту независимо от приложения, и приложение даже никогда не видит отклоненный запрос.
Как понять, кто виноват
405 почти всегда - проблема настройки сервера или кода, а не что-то, вызванное посетителем, поскольку браузеры и обычные ссылки сами по себе не отправляют произвольные методы. Если страница в основном работает, но одно действие, вроде отправки формы или вызова API из клиентского JavaScript, проваливается с 405, проверьте, совпадает ли метод именно этого запроса с тем, что ожидает эндпоинт. Если совпадает, а ошибка новая, быстрее всего подтвердить, что сломалась настройка маршрута или прокси, - запустить HTTP-проверку, отправляющую именно тот метод, который использует ваше приложение, и сравнить результат до и после недавнего деплоя.
Как исправить 405 Method Not Allowed
Если вы посетитель
- Перезагрузите страницу и повторите действие, поскольку 405 при отправке формы иногда может следовать за страницей, загрузившей устаревшую закэшированную версию формы, указывающую не на тот эндпоинт.
- Очистите кэш браузера для сайта, если проблема сохраняется, на случай если устаревший service worker или закэшированный ответ воспроизводит старый, уже несовместимый запрос.
- Сообщите об этом сайту, поскольку почти всегда это проблема настройки на их стороне; для сервера, который действительно не принимает этот метод, никакого клиентского исправления не существует.
Если вы администрируете сайт
- Прочитайте заголовок
Allowв собственном ответе 405, чтобы точно подтвердить, какие методы сервер считает валидными для этого пути, затем сравните это с тем, что реально отправляет клиент. - Добавьте недостающий метод в маршрут. В большинстве фреймворков это однострочное объявление маршрута; исправление редко находится в логике приложения, как только вы знаете, какого именно метода не хватает.
- Явно обрабатывайте OPTIONS для маршрутов с включенным CORS. Либо позвольте промежуточному ПО CORS вашего фреймворка автоматически отвечать на preflight-запросы, либо добавьте обработчик, возвращающий правильные заголовки
AllowиAccess-Control-Allow-Methods. - Исправьте блок location в nginx, если блок для статических файлов перехватывает маршрут, которому нужен бэкенд. Минимальный пример, проксирующий POST дальше вместо отдачи как файла:
location /api/ { proxy_pass http://backend; } - Проверьте белые списки методов у шлюза и балансировщика нагрузки отдельно от приложения, поскольку запрос может быть отклонен еще до того, как вообще дойдет до вашего кода, и логи приложения ничего об этом не покажут.
Как предотвратить незаметный 405 после деплоя
Маршрут, теряющий метод во время рефакторинга, либо правило прокси, начавшее перехватывать путь, который раньше не перехватывало, нигде не выбросит исключение - он просто ответит неверным, но валидным HTTP-ответом. Плановая HTTP-проверка с проверкой кода состояния, отправляемая тем же методом, на который полагается ваша интеграция, ловит эту регрессию сразу после вызвавшего ее деплоя, а не после того, как пользователи сообщат о сломанных формах. Конкретно для эндпоинтов API мониторинг API, проверяющий и метод, и тело ответа, подтверждает, что маршрут не только принимает запрос, но и по-прежнему ведет себя правильно.
Похожие ошибки
См. 404 Not Found - для пути, вообще не существующего, в отличие от существующего, но отклоняющего метод, обзор 4xx - для полного семейства, а также 401 Unauthorized и 422 Unprocessable Content в других руководствах этой партии.
Часто задаваемые вопросы
В чем разница между 404 и 405?
404 означает, что по этому пути вообще ничего не существует ни для какого метода. 405 означает, что путь существует и работает хотя бы для одного метода, просто не того, что вы использовали, а заголовок Allow подтверждает, какие методы валидны.
Почему запрос CORS проваливается с тем, что выглядит как 405?
Браузеры автоматически отправляют preflight-запрос OPTIONS перед многими межисточниковыми запросами. Если у сервера нет обработчика OPTIONS для этого маршрута, он отвечает 405, а браузер сообщает об этом как о провале CORS в консоли, а не показывает сырой код состояния напрямую.
Бывает ли 405 когда-либо правильным ответом, который API отправляет намеренно?
Да. Если ресурс действительно поддерживает только чтение, возврат 405 на PUT или DELETE к нему - правильное поведение REST, и это более информативно для вызывающего, чем был бы общий 404.
Может ли файрвол или WAF вызвать 405?
Это встречается реже, чем неправильная настройка приложения или прокси, но некоторые наборы правил WAF ограничивают разрешенные методы по пути и ответят 405 или похожей блокировкой еще до того, как запрос вообще дойдет до origin.
Почему заголовок Allow иногда перечисляет методы, которые все равно проваливаются?
Заголовок Allow отражает то, для чего зарегистрирован маршрут, а не обязательно то, что полностью реализовано. Метод может быть объявлен и все равно возвращать ошибку по другим причинам, например из-за отсутствующей авторизации, уже после того как он прошел проверку метода.