sfw/fix
405 medium

405 Method Not Allowed

The URL exists but the HTTP verb used isn't allowed on that route, most often a POST hitting a GET-only path.

What you see

405 Method Not Allowed
The requested method POST is not allowed for this URL.
Allow: GET, HEAD

What’s actually happening

The page loads fine in a browser but submitting a form throws 405. The resource clearly exists — a 404 would mean the path is wrong, but 405 means the path is right and the verb is wrong. A well-behaved server includes an Allow header listing the methods it does accept, which tells you immediately what the route expects. PUT and DELETE from a JS app commonly get 405 when the server only wired up GET and POST.

Common causes

  • A form set to method="post" submitting to a route that only handles GET (or vice versa).
  • Static hosting (S3, GitHub Pages, plain nginx serving files) where POST to a static file is meaningless and rejected outright.
  • A reverse proxy or WAF stripping or blocking POST/PUT/DELETE — some shared hosts disable methods beyond GET/HEAD/POST.
  • A REST route defined for one verb only, so PUT/PATCH/DELETE from the front end fall through to a 405.
  • A missing or wrong route in the framework router (Express app.get vs app.post, Django method check, .htaccess RewriteRule not passing the method).

How to fix it

  1. Check the Allow headercurl -sI -X POST https://example.com/submit and read the Allow line in the response. It lists exactly which methods the route accepts. If your verb isn't there, that's the whole problem.
  2. Match the form/client verb to the routeConfirm the form's method attribute and action URL line up with a route registered for that method. In Express, an app.get('/submit') route will 405 a POST — add app.post('/submit') or change the form. Same idea for Django, Rails, Laravel route definitions.
  3. Don't POST to static endpointsIf the target is a static file on S3/GitHub Pages/Netlify, there's no server-side handler to receive a POST. Point the form at an actual API endpoint, serverless function, or form-handling service instead.
  4. Unblock the method at the proxy/hostCheck nginx (limit_except), Apache (<LimitExcept>), or your host's panel for method restrictions. WAFs sometimes block PUT/DELETE by default — add a rule to allow them on the relevant paths.
  5. Handle CORS preflight for APIsBrowsers send an OPTIONS preflight before cross-origin PUT/DELETE/PATCH. If the server doesn't answer OPTIONS, you'll see a 405 on the preflight. Add an OPTIONS handler that returns the right Access-Control-Allow-Methods.

Stop it recurring

Keep form methods, fetch/XHR verbs, and server route definitions in sync, and explicitly allow the methods your API needs at every proxy in front of it.

Related errors