501 Not Implemented
Server error response defined by RFC 9110 §15.6.2.
Last updated July 27, 2026
Common causes at a glance
- A request method the server has no implementation for at all
- A reverse proxy rejecting a method its configuration does not permit
- A client using PATCH, PROPFIND, or a custom verb against a plain static server
- A proxy asked to handle CONNECT or an unsupported transfer coding
Reproduce it
curl -i -X PATCH -H 'Content-Type: application/json' -d '{}' https://api.example.com/v1/orders/1What 501 Not Implemented means
The distinction that matters is 501 versus 405. 405
Method Not Allowed says “I know this method, but not here”: DELETE on a
read-only collection, POST to a static file. 501 says “I do not implement
this method anywhere, for anything”. A server that has never heard of
PATCH returns 501. A server that implements PATCH on
/orders but not on /orders/1/audit returns 405 with an
Allow header.
Getting this backwards has a real consequence, because 405 requires that
Allow header listing what the resource does support, whereas 501 correctly
implies there is nothing to enumerate. The code also covers non-method cases, such as a
proxy asked for a transfer coding it has no implementation for.
What the spec says
RFC 9110 §15.6.2 is explicit that 501 is the
appropriate response when the server does not recognise the request method and is not
capable of supporting it for any resource. It is also the only 5xx code that is
heuristically cacheable, per
RFC 9111 §4.2.2. That
surprises people: an intermediary may reuse a 501 unless you send explicit cache
directives. Contrast §15.5.6 for 405, which mandates
Allow. Only GET and HEAD are required of
general-purpose servers (§9.1); everything else is optional, and
new methods are registered per §18.2.
What actually causes it
Static file servers are the usual source. nginx serving a directory
answers GET and HEAD and rejects most else, so an API client
pointed at the wrong hostname produces a confusing 501 rather than a 404. The other
frequent case is a WebDAV or custom verb crossing an intermediary that only knows the
standard set, since CDNs and WAFs often reject unknown methods outright. Inside
frameworks, a 501 usually means the router matched nothing and the fallback handler
picked the wrong code; most such responses should be 404 or 405.
How to debug it
Ask the server what it supports before guessing. An OPTIONS
request costs nothing and separates the two failure modes immediately:
curl -sS -X OPTIONS -D - -o /dev/null https://api.example.com/v1/orders/1
If the response carries an Allow header, the server understands methods
per-resource and your 501 is probably coming from a hop that never reached the
application. If there is no Allow, the method is genuinely unimplemented.
Repeat the request straight at the origin: a 501 that disappears when you skip the CDN
is a proxy method allowlist, not an application limitation. Because 501 can be cached,
purge the edge or add Cache-Control: no-store once you fix the route.
Working examples
curl
# OPTIONS separates "method unknown anywhere" from "method not allowed here".
curl -sS -X OPTIONS -D - -o /dev/null https://api.example.com/v1/orders/1
# Then the real method: read the status and any Allow header.
curl -sS -X PATCH -D - -o /dev/null \
-H 'Content-Type: application/merge-patch+json' \
-d '{"status":"shipped"}' \
https://api.example.com/v1/orders/1
Python (requests)
import requests
url = "https://api.example.com/v1/orders/1"
opts = requests.options(url, timeout=10)
print("allow:", opts.headers.get("Allow"))
resp = requests.patch(url, json={"status": "shipped"}, timeout=10)
if resp.status_code == 501:
print("method not implemented by this server at all")
elif resp.status_code == 405:
print("method not allowed here; try:", resp.headers.get("Allow"))
Node (fetch)
const url = "https://api.example.com/v1/orders/1";
const opts = await fetch(url, { method: "OPTIONS" });
console.log("allow:", opts.headers.get("allow"));
const res = await fetch(url, {
method: "PATCH",
headers: { "Content-Type": "application/merge-patch+json" },
body: JSON.stringify({ status: "shipped" }),
});
console.log(res.status, res.status === 501 ? "unimplemented" : res.headers.get("allow"));Reference and tooling
The authoritative list of assigned status codes is theIANA HTTP Status Code Registry. For a searchable copy with the semantics summarised, use theHTTP status code reference on this site. To see exactly what a server is sending, theheader inspector shows the raw status line and response headers, and thecurl builder assembles the request flags for you.
Other 5xx codes
- 500 Internal Server Error
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
- 505 HTTP Version Not Supported
- 506 Variant Also Negotiates
- 507 Insufficient Storage
- 508 Loop Detected
- 510 Not Extended
- 511 Network Authentication Required
- 520 Web Server Returns an Unknown Error
- 521 Web Server Is Down
- 522 Connection Timed Out
- 523 Origin Is Unreachable
- 524 A Timeout Occurred
- 525 SSL Handshake Failed
- 526 Invalid SSL Certificate
- 530 Unable to Resolve Origin Hostname