HTTP 501 Not Implemented
Quick reference
| Code | 501 |
|---|---|
| Name | Not Implemented |
| Category | 5xx Server Error |
| Spec | RFC 9110 §15.6.2 |
| Cacheable? | Yes — by default (RFC 9110 §15.6.2) |
What 501 means
HTTP 501 Not Implemented means the server does not support the functionality required to fulfill the request. The most common trigger is an HTTP method the server does not recognize or has not implemented. RFC 9110 §15.6.2 states that 501 is appropriate when the server "does not recognize the request method and is not capable of supporting it for any resource."
501 is a server-level declaration of ignorance about a method — not a per-resource refusal. If the server knows the method but a specific resource does not support it, the correct code is 405 Method Not Allowed (with an Allow: header listing the supported methods). If the server recognizes the method but refuses to apply it to a specific resource for access reasons, 403 or 405 are more appropriate than 501.
RFC 9110 notes that 501 is cacheable by default — caches may store and replay a 501 response for the same method on the same URL. This matters because if a server returns 501 for a custom method and then implements it later, cached 501 responses may continue to be served. Set Cache-Control: no-store on 501 responses if implementation is expected in the future.
501 vs 405: the key distinction
The difference between 501 and 405 is whether the server has any knowledge of the method at all:
| Scenario | Correct code | Include Allow header? |
|---|---|---|
Server does not recognize the method (e.g. FROBNICATE /resource) | 501 | No — the server does not know what methods are supported for this type of resource |
Server knows the method but this resource does not support it (e.g. DELETE /readonly-resource) | 405 | Yes — include Allow: GET, HEAD |
| Server knows the method, resource supports it, but client lacks permission | 403 | No |
In practice, web frameworks and HTTP servers return 405 for most "wrong method" scenarios because they implement all standard HTTP methods and know the allowed set for each route. 501 surfaces from middleware layers that encounter entirely foreign request methods from non-standard HTTP clients, protocol bridge implementations, and security scanners probing for methods like TRACK, DEBUG, CONNECT, or PROPFIND on non-WebDAV servers.
When servers return 501
Unrecognized HTTP extension methods: Security scanners often send methods like TRACE, TRACK, DEBUG, or SEARCH. Web servers that do not implement these return 501. nginx returns 501 for TRACE requests by default since version 1.9.5.
WebDAV methods on non-WebDAV servers: A client sending PROPFIND, MKCOL, COPY, or LOCK to a server that does not implement WebDAV gets 501. The server recognizes these as valid HTTP extension methods but has not implemented them.
HTTP extension methods from older protocols: PATCH was added to HTTP in RFC 5789 (2010). Older servers or reverse proxies that predate PATCH support may return 501 for PATCH requests. This is now rare but still encountered in legacy enterprise systems.
Proxy CONNECT on non-proxy servers: The CONNECT method is for establishing tunnels through proxies. A direct origin server that does not function as a proxy returns 501 for CONNECT requests.
Returning 501 from application code
Application code should rarely return 501 directly — framework routing handles method dispatching and returns 405 for unknown routes. A valid use case is a planned-but-not-yet-implemented endpoint:
# Express.js — placeholder for future implementation
app.post('/api/v2/advanced-search', (req, res) => {
res.status(501).json({
error: 'not_implemented',
message: 'Advanced search is not yet available. Use /api/v1/search.',
docs: 'https://docs.example.com/api/search'
});
});
# Django REST Framework — placeholder view
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class FutureFeatureView(APIView):
def post(self, request):
return Response(
{'error': 'not_implemented', 'eta': '2026-Q3'},
status=status.HTTP_501_NOT_IMPLEMENTED
)
Frequently asked questions
Should 501 include an Allow header?
No. RFC 9110 does not require an Allow: header with 501. The server does not know what methods are supported for the resource because it does not understand the requested method at all. Allow: headers are required with 405, not 501.
Why is 501 cacheable by default?
RFC 9110 lists 501 among the status codes that are cacheable by default (along with 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 451). The rationale is that "not implemented" is a relatively stable server property — a server that does not implement FROBNICATE today is unlikely to implement it tomorrow. Add Cache-Control: no-store if you expect implementation to change.
Is 501 ever returned for request body features?
Rarely, but yes. A server might return 501 if a request includes an extension like Transfer-Encoding: chunked and the server does not support chunked transfer. More commonly, servers return 400 for these cases. 501 for request feature support is less consistent across implementations.
What does nginx return for TRACE requests?
nginx returns 405 Method Not Allowed for TRACE requests with an empty Allow: header. Apache returns 405 as well but with a populated Allow: header. Some older server versions return 501 for TRACE. The exact behavior depends on server version and configuration.