What causes a 405 error
- The wrong method. Sending
POSTwhere the endpoint expectsPUT, orGETwhere it expectsPOST. - A redirect that changed the method. When a server answers a
POSTwith a 301 or 302 redirect, many clients (browsers, Python requests, and curl with-L) follow it with aGET. A missing or extra trailing slash is a common trigger. - The wrong URL. A form or script posting to a page's URL instead of the API endpoint behind it.
- A static file server. Many servers that only serve files answer 405 to anything but
GETandHEAD. - Methods turned off on purpose, such as
PUT,DELETEorTRACEdisabled in the server or firewall configuration.
Did the proxy or the site send the 405?
Almost always the site or API. A forward proxy passes your method through unchanged, and inside an HTTPS tunnel it can't even see it. The Allow header in the response comes from the server that owns the URL.
To confirm, send the same request without the proxy. The same 405 means the proxy isn't involved.
How to fix a 405 error
- Read the
Allowheader in the 405 response. It lists the methods the URL accepts. - Check the API docs for the endpoint's method and exact path, trailing slash included.
- Look for redirects: send the request with redirects turned off. If a 301 or 302 comes first, send your request to the final URL instead. On your own server, use 307 or 308 redirects, which keep the method.
- On your own site, make sure the route handles that method, and that the server or firewall doesn't block it.
Find the allowed methods: curl and Python
# -i shows the status and headers: look for the Allow header in a 405
curl -i -X POST https://api.example.com/items
# Some servers also answer OPTIONS with the allowed methods (not all do)
curl -i -X OPTIONS https://api.example.com/items
# No -L, so curl stops at a 301 or 302 instead of following it with a GET
curl -sS -o /dev/null -D - -X POST https://api.example.com/itemsimport requests
r = requests.post(
"https://api.example.com/items",
json={"name": "test"},
allow_redirects=False, # see the redirect instead of following it with a GET
timeout=30,
)
if r.status_code in (301, 302, 303):
print("Redirected to", r.headers.get("Location"), "(post there directly)")
elif r.status_code == 405:
print("Allowed methods:", r.headers.get("Allow"))405 errors when you use proxies
With an HTTP proxy line, plain http:// requests are forwarded as normal requests and https:// requests travel through a CONNECT tunnel. Both carry your method and path unchanged, so a 405 through a proxy is the same 405 you would get without one.
Rotating IPs or changing the session type won't affect it. Fix the request: the method, the URL, and any redirect in between.
405 Method Not Allowed: frequently asked questions
What does a 405 error mean?
The server recognises the URL but doesn't accept the HTTP method you used, such as a POST to a page that only allows GET.
How do I fix a 405 Method Not Allowed error?
Check the Allow header in the response for the accepted methods, confirm the method and path in the API docs, and look for a redirect that turned your POST into a GET.
What is the difference between 405 and 404?
404 means the server has nothing at that URL. 405 means the URL exists but doesn't accept that method.
Why do I get a 405 on a POST that used to work?
A common reason is that the URL now redirects, for example to add a trailing slash, and the client follows the redirect with a GET. Send the POST to the final URL directly.