Skip to content

405 Method Not Allowed: What It Means and How to Fix It

Updated 6 min read

Updated: 12 October 2026 · Applies to: Nginx 1.28, Apache 2.4.66 and PHP 8.5 (tested on Ubuntu 26.04), Laravel 13.35, Flask 3.1, WordPress 7.1 and IIS (according to Microsoft)

405 Method Not Allowed means the server found the URL but refuses the HTTP method of the request: GET, POST, PUT, DELETE and so on. Nginx shows the same error as 405 Not Allowed. The page exists, but it does not accept that kind of request: most often a form that POSTs to a static page, PHP that Nginx does not hand to PHP-FPM, an API called with the wrong method, or a redirect that turned a POST into a GET. If the response has an Allow header, it lists the methods that do work.

If you are only visiting the site

A 405 is not caused by your browser or connection. Go back and open the page again from the site's own menu rather than reloading after a form was sent. If a form keeps failing, tell the site owner which page and which button gave the error.

Find the cause

  1. Repeat the request with curl and look at the status and the Allow header:
    curl -si -X POST -d test=1 https://example.com/contact | grep -iE "^HTTP|^allow"
    curl -si -X OPTIONS https://example.com/api/items | grep -iE "^HTTP|^allow"
  2. Open the browser's developer tools (F12), Network tab, send the form again and check the request method, the status and whether a 301 or 302 came first.
  3. Read the access log (/var/log/nginx/access.log or /var/log/apache2/access.log). This lab log shows the redirect trap described below: a POST got a 301, and the browser-style follow-up GET got the 405:
    "POST /old-subscribe HTTP/1.1" 301 178 "-" "curl/8.18.0"
    "GET /php/subscribe.php HTTP/1.1" 405 19 "-" "curl/8.18.0"

What each server and framework does

We sent different methods to Nginx, Apache, PHP and two frameworks on a test server. This is what came back:

Nginx

  • POST, PUT, DELETE and OPTIONS to a static file (.html, or / when the index is index.html) return 405 Not Allowed. GET and HEAD work. Nginx's error page has no Allow header (lab output, shortened):
    HTTP/1.1 405 Not Allowed
    Server: nginx/1.28.3 (Ubuntu)
    Content-Type: text/html
    
    <head><title>405 Not Allowed</title></head>
  • A POST to a .php file in a location without a PHP handler also returned 405, because Nginx served the file as a static file. The same request to a location with fastcgi_pass to PHP-FPM ran the script.
  • limit_except GET { deny all; } answers other methods with 403, not 405.

Apache

  • A POST to a static file returned 200, but PUT and DELETE returned 405 Method Not Allowed with Allow: GET,POST,OPTIONS,HEAD and the text The requested method PUT is not allowed for this URL.
  • TRACE returned 405 because Ubuntu's security.conf sets TraceEnable Off; that is intended (see disable TRACE in Apache).
  • AllowMethods GET OPTIONS (mod_allowmethods) answers other methods with 405 and logs AH01623: client method denied by server configuration. <LimitExcept GET> with Require all denied answers 403 instead.

PHP, Laravel, Flask and WordPress

  • Your own PHP script can send a correct 405 itself: http_response_code(405); header('Allow: POST'); before any output.
  • Laravel: a GET to a route defined with Route::post returned 405 with Allow: POST and, with APP_DEBUG=true, The GET method is not supported for route subscribe. Supported methods: POST. With debug off, visitors only see Method Not Allowed. A very common case is an HTML form for a Route::put or Route::delete route: forms can only send POST, so you get The POST method is not supported for route profile. Supported methods: PUT. Add @method('PUT') inside the form; Laravel then reads the hidden _method field. If the error changes to 419, the CSRF token (@csrf) is missing.
  • Flask: a GET to a route with methods=["POST"] returned 405 METHOD NOT ALLOWED, Allow: OPTIONS, POST and The method is not allowed for the requested URL.
  • WordPress: opening xmlrpc.php in a browser gives 405 with XML-RPC server accepts POST requests only. That is how WordPress's XML-RPC server is written (we checked the 7.1.3 source); nothing is broken.

IIS on Windows Server

According to Microsoft, IIS returns HTTP Error 405.0 - Method not allowed when a POST goes to a page handled by the StaticFile handler, when the request uses a method that does not follow the HTTP specification, or when WebDAV Publishing interferes with PUT requests. For the last case, Microsoft's fix is to remove the WebDAV modules and handlers from web.config, or to remove the WebDAV Publishing feature if you do not use it.

The redirect trap: POST turned into GET

Browsers follow a 301 or 302 after a POST with a GET. In our test, a POST to an address that answered 301 was repeated as GET and ended in 405, while the same POST through a 308 redirect kept its method and got 200. Typical triggers are a form that posts to http:// while the site redirects to https://, a missing or extra trailing slash, or a moved page. Point forms and API clients at the final URL; for an endpoint that must receive POSTs at an old address, redirect with 307 or 308. See redirect HTTP to HTTPS and 301, 302, 307 and 308 explained.

Fix it

  1. Use the right method. Check the Allow header or the API documentation and send GET, POST, PUT or DELETE as listed.
  2. Send forms to a script, not a page. A form's action must point at something that processes it (a PHP file, an application route or a form service), not at an .html page.
  3. On Nginx, connect PHP. Make sure the location that serves the file passes .php to PHP-FPM, then run sudo nginx -t && sudo systemctl reload nginx.
  4. On Apache, check the method rules. Look for AllowMethods in the virtual host or .htaccess; the error log names the denied method.
  5. In your application, allow the method on the route if it should be accepted: Route::match(['get', 'post'], ...) in Laravel, methods=["GET", "POST"] in Flask.
  6. Remove redirects from the request path by calling the final https:// URL directly.

If you get 403 instead of 405, the method is blocked by an access rule such as limit_except, LimitExcept or a security filter, not by the page itself. Stuck with a custom application? Our engineers can look at it through Hire an Expert.

Official documentation: MDN: 405 Method Not Allowed and Microsoft: HTTP 405.0 errors in IIS.

Related services

KVM VPS hosting

NVMe SSD and full root access, with Free Basic Managed Support.

Unmanaged dedicated servers

full root access and free IPMI KVM, with Free Basic Managed Support.

Linux server management

hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.

Was this answer helpful?

Still stuck? Open a ticket