A 405 “Method Not Allowed” error means the server received your request but rejected the specific HTTP method used to send it, whether that’s GET, POST, PUT, DELETE, or another verb. It’s a frustrating error precisely because it often happens on actions that should just work, like logging in, submitting a form, or updating a record, and pinning down the exact cause can take some digging.
What a 405 Error Actually Means
When a server returns a 405, it’s confirming that the resource exists, but the specific method your request used isn’t permitted for it. The response typically includes an “Allow” header listing which methods are actually accepted for that resource, which is one of the first places worth checking when troubleshooting.
Common Causes Behind the Error
Wrong HTTP method for the endpoint
REST APIs tend to be strict about method contracts. An endpoint might accept POST to create a record but reject PUT because updates are expected to happen at a different path, like /users/{id} instead of /users. Sending the technically “right” verb to the wrong endpoint level still returns a 405.
Server configuration blocking the method
Apache and Nginx can restrict HTTP methods directly at the configuration level. A rule intended to lock down something like DELETE or PUT for security reasons can end up overreaching and blocking legitimate traffic that should have gone through.
Redirects that don’t preserve the original method
If a server or an intermediary layer, like .htaccess or middleware, performs a redirect without preserving the original request method, a POST can silently get converted into a GET during the redirect, and the resulting request gets rejected. This is especially common when a site redirects between HTTP and HTTPS, or normalizes trailing slashes on URLs.
Plugin or theme conflicts (common on WordPress)
WordPress sites are particularly prone to this. Installing a new plugin can register custom rewrite rules or REST API routes that collide with existing .htaccess rules, causing 405 errors on form submissions, even though the plugin works fine in isolation. The issue is the interaction with existing configuration, not the plugin alone. Uninstalled extensions can also leave orphaned database records or custom post type registrations behind, which can confuse routing logic later.
The Cloudflare WAF Connection
One cause worth calling out specifically, since it trips up a lot of site owners: Web Application Firewalls, including Cloudflare’s, can override your server’s own configuration entirely. WAF rules frequently block specific HTTP methods like PUT, DELETE, PATCH, TRACE, or OPTIONS on certain paths as a security measure, producing a 405 even when your actual origin server would have allowed the request just fine.
The trouble starts when these rules are too broad. A rule that blocks DELETE across an entire domain sounds reasonable in isolation, until an admin dashboard needs DELETE to remove records, and suddenly a legitimate feature breaks.
This matches a resolution some users have reported directly: the issue traced back to Cloudflare’s zone-level Web Application Firewall, specifically the Managed Rules and JavaScript challenges being applied to requests they shouldn’t have been touching, such as login POST requests.
To check and fix this in Cloudflare specifically:
- Open the Cloudflare dashboard and navigate to the WAF section for the affected zone
- Review the Managed Rules and check the security event logs for any rule that triggered on the request path in question (such as your login endpoint)
- Look specifically for JavaScript challenge rules, since these can interfere with POST requests like logins if applied too broadly
- If you recently enabled or updated WAF rules and 405 errors started appearing around the same time, that timing is a strong signal the WAF is the cause
- Rather than disabling a rule outright, whitelist the specific legitimate method or add an exception for the affected path or route
- Save changes and retest the exact action that was failing
General Troubleshooting Steps
- Check the Allow header in the actual 405 response, since it tells you exactly which methods the server considers valid for that resource
- Review the API or endpoint documentation to confirm the method you’re sending matches what the resource actually supports
- Check your client code or form configuration to make sure it’s not sending an unexpected method (for example, a script using
fetch() with POST when the endpoint only accepts GET)
- Look at server-level configuration in Apache or Nginx for any method-blocking rules that might be too broad
- Check firewall and security plugin logs on the origin server itself, not just at the CDN or WAF layer, since WordPress REST API routes (paths starting with
/wp-json/) are a common trigger point
- Test with WAF or security proxies temporarily disabled to confirm whether they’re actually the source, then re-enable with more targeted rules once you’ve isolated the cause
Framework-Specific Notes
In frameworks like Symfony and Laravel, a 405 is the specific exception thrown when a request’s path matches a defined route, but the HTTP method doesn’t match what that route expects. Seeing this error in those frameworks means the route itself exists, just registered for a different verb, so the fix usually involves correcting the route definition or adding a handler for the method actually being sent.
Join The Discussion
405 errors are one of those problems where the fix can be a one-line config change or a genuine rabbit hole through WAF rules, redirects, and plugin conflicts. Have you run into a 405 error caused by Cloudflare’s WAF or a similar security layer, and what finally resolved it for you? Share your experiences, troubleshooting steps, or questions below, especially if you’ve found a reliable way to pinpoint whether a WAF is the culprit before diving into server configs.