apyhub
Engineering

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

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

01Introduction

A 405 Method Not Allowed error means the server understood your request and recognizes the HTTP method you used — GET, POST, PUT, DELETE — but that method isn't permitted on the resource you called. The route exists; the verb is wrong for it.

The quickest tell is in the response itself. Per the HTTP specification (RFC 9110, §15.5.6), a server returning 405 must include an Allow header listing the methods the resource does accept. That header is the fix hiding in plain sight — it tells you exactly which method to switch to.

Here's a 405 in practice. You send a POST to a read-only endpoint:

· http
POST /api/data HTTP/1.1
Host: example.com
Content-Type: application/json

{"key": "value"}

The server responds:

· http
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
Content-Type: text/html

Translation: this resource takes GET or HEAD, not POST. The error isn't the hard part — figuring out why the method is blocked, when the endpoint, the server config, and a framework router can all be the cause, is where the time goes.

02What a 405 Actually Means

HTTP methods define the action a request performs: GET reads, POST creates, PUT and PATCH update, DELETE removes. Every resource on a server declares which of those it supports. When your method isn't on that list, the server rejects the request with a 405 rather than attempting it.

The distinction that trips people up: a 405 is not "the server broke" and not "the page doesn't exist." The server is working correctly and the resource is there. It's specifically saying this verb is not valid here — and it's obligated to tell you which verbs are.

03405 vs 400, 401, 403, 404, and 501

405 is easy to confuse with the status codes around it. They fail for genuinely different reasons, and reading the wrong one sends you debugging the wrong thing:

CodeNameWhat it actually meansHow it differs from 405
400Bad RequestThe request itself is malformed — bad syntax, invalid JSON, missing required fields.The verb is fine; the content is broken. A 405 is a well-formed request with the wrong method.
401UnauthorizedAuthentication is missing or failed.401 is about who you are. 405 doesn't care who you are — the method is wrong for everyone.
403ForbiddenYou're authenticated but not permitted to do this.403 is a permission decision on an allowed action. 405 means the action (method) itself isn't allowed on the resource.
404Not FoundThe resource or route doesn't exist.404 = the path is wrong. 405 = the path is right, the method is wrong.
501Not ImplementedThe server doesn't support the method at all, for any resource.501 is server-wide ("we don't do PATCH here, anywhere"). 405 is resource-specific ("this endpoint doesn't do PATCH, others might").

If you remember one line: 404 means the door isn't there; 405 means the door is there but locked to that knock.

04What Triggers a 405

The error surfaces in a handful of recurring situations:

  1. Wrong HTTP method for the endpoint. REST APIs are strict. /users might accept POST to create a record but reject PUT because updates happen at /users/{id}. Sending the right verb to the wrong level still returns 405.
  2. Server configuration blocking the method. Apache and Nginx can restrict methods at the config level. A rule meant to lock down DELETE or PUT for safety can overreach and block legitimate traffic.
  3. API endpoint rules. A GET-only endpoint hit with DELETE returns an immediate 405. This is the endpoint enforcing its own contract, and it's easy to miss when the docs aren't in front of you.
  4. Security filtering. Web Application Firewalls (WAFs) like Cloudflare sometimes block methods such as TRACE, OPTIONS, or PATCH to reduce attack surface — producing 405s even when the origin server would have allowed the method.
  5. Framework routing gaps. In most web frameworks, a route registered for one method won't answer another. Depending on the framework, sending the wrong verb returns either a 405 or a 404 (more on that below).

05How to Fix a 405 Method Not Allowed Error

The fix is always: find the cause, then correct the request or the config. Work through these in order.

1. Confirm which method the endpoint expects

Read the Allow header on the 405 response first — it lists the valid methods. If you don't have one, probe the endpoint with OPTIONS:

· bash
curl -X OPTIONS https://api.example.com/users -i

A typical response:

· http
HTTP/1.1 200 OK
Allow: GET, POST, HEAD

Match your request to that list. If it says Allow: POST and you were sending PUT, that's your answer.

2. Check the server configuration

If the endpoint should accept your method but doesn't, inspect the server config.

Apache — look for Limit directives in .htaccess or httpd.conf:

· apache
<Limit GET POST PUT>
    Order Allow,Deny
    Allow from all
</Limit>

Nginx — check limit_except in the relevant location block:

· nginx
location /api {
    limit_except GET POST DELETE {
        deny all;
    }
}

Reload after changes (systemctl reload apache2 or nginx -s reload).

3. Check security filters and WAF rules

If a WAF sits in front of the origin, review its ruleset — it may be stripping methods before they reach your server. Whitelist the legitimate method rather than disabling the rule wholesale, so you don't trade a 405 for an actual vulnerability.

4. Fix the framework route

Make sure a handler exists for the method you're sending. In Express:

· javascript
app.delete('/posts/:id', (req, res) => {
  // delete logic
});

No DELETE handler means no valid response for that verb.

5. Rule out permissions

If the method is allowed but tied to a role, a missing or wrong token can produce a 405 or 403. Send the request with auth attached and compare:

· bash
curl -X DELETE https://api.example.com/posts/1 \
  -H "Authorization: Bearer <token>" -i

6. Read the server logs

Logs tell you whether the block came from config or from the method itself. Nginx (/var/log/nginx/error.log):

2026/06/30 10:00:00 [error] 1234#0: *1 method not allowed

Apache (/var/log/apache2/error.log):

[Tue Jun 30 10:00:00.2026] [error] Method PUT not allowed for /api/data

Follow the trail from there to the config line or route responsible.

06Framework-Specific 405s (and the "works in the browser, fails in the client" case)

A recurring source of confusion: the same URL behaves differently depending on what sends the request. Pasting a URL into a browser issues a GET. An API client — Postman, curl, Voiden — can issue POST, PUT, or DELETE. So a route that only accepts GET will load fine in a browser and then return a 405 (or a 404) the moment a client sends a different verb. If a request "works in the browser but not in the client," check the method before anything else.

How different stacks report the same underlying problem:

  • Laravel / Symfony throw MethodNotAllowedHttpException (from Symfony\Component\HttpKernel\Exception) when the path matches a route but the HTTP method doesn't. Seeing MethodNotAllowedHttpException in a stack trace is the framework telling you the route exists for a different verb — check your Route:: definitions or the controller's allowed methods.
  • Spring raises HttpRequestMethodNotSupportedException, mapped to 405, when no handler matches the request method.
  • Django REST Framework returns its MethodNotAllowed exception as a 405 when a viewset doesn't implement the method.
  • Express is the exception worth knowing: by default it does not return 405 for an unhandled method — it falls through to a 404 (Cannot POST /posts). To get a proper 405 with an Allow header, you handle it explicitly (for example with app.all() on the route, or a router that tracks registered methods). If you expected a 405 and got a 404 in Node, this is usually why.

07Testing and Reproducing a 405

Reproducing the error deliberately is the fastest way to confirm the cause. Three tools cover most workflows:

  • curl — the quickest way to fire a single request with an explicit method and read the raw Allow header. Ideal for one-off checks:
    · bash
    curl -X PUT https://api.example.com/data -i
  • Postman — a GUI client for sending requests across methods and inspecting responses, useful when you're clicking through an API interactively.
  • Voiden — an offline-first, Git-native API client that stores requests as Markdown-based .void files you can version alongside your code. Because the requests live in your repo, the exact POST-vs-PUT call that triggered a 405 is committed, diffable, and reproducible by anyone who checks out the branch — rather than trapped in one person's local client. Voiden is open source (Apache 2.0); you can download it here.

None of these fix the server — they let you see precisely which method the resource accepts, so you correct the request with certainty instead of guessing.

08Where ApyHub Fits

A large share of 405s in day-to-day work come from calling an endpoint with the wrong verb because the method contract wasn't obvious. That's a documentation-and-consistency problem as much as a coding one.

ApyHub is a certified API marketplace — a catalog of 200+ APIs and 1,000+ endpoints for the utility work most products need (file conversion, data validation, PDF processing, enrichment, and more). Every endpoint in the catalog ships with a documented, machine-readable specification, including the methods it accepts, so the "which verb does this take" question is answered before you write the call — and answerable by AI agents consuming the catalog through MCP, not just humans reading docs. It doesn't make 405s impossible, but it removes one of the most common ways developers stumble into them: guessing at an undocumented method contract.

Explore the catalog →

09Conclusion

A 405 Method Not Allowed error is a signal, not a mystery: the resource exists, the method doesn't fit it, and the Allow header is telling you what does. Confirm the expected method, check server config and WAF rules, verify your framework route, and read the logs — in that order — and the fix is usually a one-line change. The habit that prevents most of them is knowing an endpoint's method contract before you call it, rather than discovering it from a rejected request.

Try ApyHub →

10FAQ

What exactly causes a 405 Method Not Allowed error?

The server recognizes your HTTP method but the specific resource you called doesn't permit it — for example, sending DELETE to an endpoint built only for GET and POST. The response includes an Allow header listing the methods that are accepted, which tells you what to switch to.

How do I find out which HTTP methods an endpoint supports?

Read the Allow header on the 405 response, or send an OPTIONS request: curl -X OPTIONS https://api.example.com/resource -i. The response's Allow header lists every method the endpoint accepts.

What's the difference between a 403 and a 405 error?

A 403 Forbidden means you're not permitted to perform an action you're otherwise allowed to request — it's about authorization. A 405 means the HTTP method itself isn't valid for that resource, regardless of who you are.

What's the difference between a 404 and a 405?

A 404 means the route or resource doesn't exist. A 405 means the route exists but doesn't accept the method you used. If you're getting a 404 when you expected a 405, your framework may be treating an unhandled method as a missing route (Express does this by default).

Why does my request work in the browser but fail in Postman or curl?

A browser issues a GET when you load a URL, while an API client can send POST, PUT, or DELETE. A route that only allows GET will load in the browser and return a 405 (or 404) from the client. Check the method your client is sending first.

What does MethodNotAllowedHttpException mean?

It's the exception Symfony and Laravel throw when a request's path matches a defined route but its HTTP method doesn't. Seeing it means the route exists for a different verb — check your route definitions and correct the method or add a handler for the one you're sending.

Can a Web Application Firewall cause a 405 error?

Yes. WAFs such as Cloudflare may block methods like TRACE, PATCH, or OPTIONS to reduce attack surface, producing a 405 even when the origin server would allow the method. Review the WAF ruleset and whitelist the legitimate method rather than disabling the rule.

How do I prevent 405 errors during development?

Validate each request against the endpoint's method contract before deploying, and keep those contracts documented and version-controlled so the whole team calls endpoints the same way. Consuming APIs whose specifications already declare their accepted methods removes the most common cause — guessing at an undocumented verb.