Website Checker - HTTP 405 Method Not Allowed: Why Your POST Just Got Rejected

HTTP 405 Method Not Allowed: Why Your POST Just Got Rejected

Jul 28, 2026 · HTTP Status Codes

A designer friend moved a client's site to a static hosting platform — fast, cheap, no server to maintain. The contact form looked perfect and failed on every submission with HTTP 405 Method Not Allowed. Of course it did: the form was POSTing to /contact.html, and a static file server has exactly one answer for POST requests to an HTML file. The page existed. The server was fine. The verb was the problem.

That's the 405 status code in miniature: the URL routes somewhere real, but the HTTP method you used isn't on the guest list for that route.

Reading a 405 status code correctly

HTTP requests carry a method — GET to fetch, POST to submit, PUT and PATCH to update, DELETE to remove. Every route on a server accepts some subset of these. A 405 is the server saying: I recognize this URL, I could answer a different method here, but not the one you sent. That's a usefully narrow diagnosis. Compare its neighbors: a 404 means the URL matched nothing at all, and a 403 means you're not allowed regardless of method. A 405 hands you the exact axis to investigate, and even tells you the answer — which brings us to the one header that matters.

The Allow header is the answer key

The spec requires every 405 response to include an Allow header listing the methods that would work:

Allow: GET, HEAD, OPTIONS

Read that from a failing endpoint and the diagnosis is done. If your form POSTs somewhere that allows only GET, either the form's action points at the wrong URL or the route is missing its POST handler. Check it directly — send the failing method deliberately and inspect what comes back:

curl -si -X POST -d "name=test" https://example.com/contact -o /dev/null -D - | grep -iE "^(HTTP|allow)"

One caveat from the field: plenty of frameworks return 405 without the Allow header, spec or no spec. When it's absent, probe with an OPTIONS request (curl -si -X OPTIONS against the same URL) or go read the route definitions.

The scenarios that produce almost every 405

  • Forms POSTing to static files, as above. Static hosts (S3 websites, GitHub Pages, most CDN-only setups) serve GET and HEAD, full stop. The form needs a real backend: a serverless function, a form-handling service, or an API endpoint on another host.
  • Route defined for the wrong method. In every web framework, a route declared as GET-only rejects POSTs with a 405 the framework generates for you. The classic Django version: a form template posts to a view whose code only handles GET, or a trailing-slash redirect turns the POST into a GET and confuses everything downstream.
  • Redirects downgrading the method mid-flight. This one's sneaky. A POST to /api/orders hits a 301 to /api/orders/, the client follows it as a GET, and the destination — which happily accepts POST — throws 405 at the GET. The fix is either posting to the canonical URL directly or using method-preserving redirects (308 for permanent, 307 for temporary) on API paths.
  • Server or security layer blocking methods wholesale. Hardening guides love disabling "unused" methods; sometimes PUT and DELETE get blocked at the web server or WAF while the application behind it needs them. WebDAV modules in IIS are notorious for intercepting PUT/DELETE before the app ever sees them.
  • CORS preflights hitting an OPTIONS-less route. Browsers send OPTIONS before cross-origin requests; an API that never registered an OPTIONS handler answers 405 and the browser abandons the real request. The visible symptom is a CORS error in the console, and the 405 underneath is easy to miss.

Fixing it at the right layer

Work from the outside in. If a WAF or server config blocks the method, no application change will help — on Apache, look for <LimitExcept GET POST HEAD> blocks or Limit directives in httpd.conf and .htaccess; on nginx, grep for limit_except. If the server passes the method through, the fix is in your routing: add the missing handler, correct the form's action URL, or register the OPTIONS route for CORS. And if a redirect is eating the method, make clients hit the final URL directly — on API endpoints, trailing-slash redirects cause enough of this that many teams disable slash normalization for API paths entirely.

For the static-host form specifically, don't fight the platform. Wire the form to a function endpoint or a form service, and keep the static files doing what they're good at.

Crawlers and the 405 you'll never see in analytics

Search engines fetch with GET and HEAD, so a correctly built site should serve them essentially zero 405s. When 405s do show up in a crawl report, it usually means GET itself is blocked somewhere strange — a security rule gone too broad, or an endpoint that only speaks POST being linked as if it were a page. A URL that answers GET with 405 can't be indexed, and if internal links point at it, you're spending crawl requests on uncrawlable targets. The quiet cost is on the user side anyway: forms and checkout steps failing with 405s happen after the pageview fires, so analytics look healthy while submissions silently die. A site-wide crawl that records every URL's status code catches the GET-facing half of the problem; testing your forms after each deploy catches the other half.

The regression guard is cheap: for every form and API endpoint, one smoke test that sends the real method and asserts a non-4xx answer. The 405 class of bug loves to arrive via "harmless" infrastructure changes — a new CDN, a hardening pass, a slash-normalization rule — and a post-deploy check turns each of those from a weekend incident into a failed pipeline.

Frequently Asked Questions

What causes a 405 Method Not Allowed error?

The URL exists but doesn't accept the HTTP method used — most often a form POSTing to a static file or a route only defined for GET, a redirect converting POST to GET mid-flight, or a server rule blocking methods like PUT and DELETE. The Allow header in the 405 response lists which methods the URL does accept, which usually identifies the mismatch immediately.

Why does my form return 405 on a static hosting platform?

Static hosts like GitHub Pages or S3 websites only serve files with GET and HEAD — there's no server-side code to receive a POST, so the platform rejects it with 405. Point the form at something that can process submissions: a serverless function, a hosted form service, or an API on a separate backend.

Can redirects cause 405 errors?

Yes, and it's a common hidden cause on APIs. If a POST hits a 301 or 302 redirect — often just a trailing-slash normalization — many clients follow it as a GET, and the destination rejects the wrong method with a 405. Either have clients call the canonical URL directly or use 307/308 redirects, which require the method to be preserved.

Try WebsiteChecker.Tech Free

Run a free technical SEO audit on any website. Get a client-ready report in minutes.

Start Free Scan