Troubleshooting

501 Not Implemented: why the server refuses the method, and how to fix it

A 501 error means the server does not support the request's method or feature. Test it with curl, see what nginx and Apache answer, and fix that layer.

Published ~8 min read
On this page

Short answer: a 501 Not Implemented error means the server does not support what the request asked for, usually the HTTP method: a WebDAV method such as PROPFIND, or PUT and DELETE sent to a server that only serves files. Less often it is a Transfer-Encoding the server cannot decode. Fix it on the server or proxy that answered.

Linux · macOS · WSL · repeat the failing request
# Which method fails? Send it yourself and read the status line
curl -s -i -X PUT --data 'hello' https://example.com/upload/test.txt | head -n 5
curl -s -i -X PROPFIND -H 'Depth: 1' https://example.com/dav/ | head -n 5

# What does the server say it accepts, and which software answers?
curl -s -i -X OPTIONS https://example.com/ | grep -i -E '^(HTTP|allow|server)'

Replace the URL with the one that fails, and the method with the one your app, client or log shows. Do not test HEAD with -X HEAD: curl then waits for a body that never comes. Use curl -I instead. More request recipes are in the curl examples guide.

What does 501 Not Implemented mean?

RFC 9110, the current HTTP specification, defines it in one sentence: the server “does not support the functionality required to fulfill the request”, and it is the right answer “when the server does not recognize the request method and is not capable of supporting it for any resource”. The key words are for any resource. A server that knows the method but does not allow it at this URL should say 405 Method Not Allowed instead. RFC 9112 adds a second case: a request with a transfer coding the server does not understand should also get a 501.

StatusWhat it saysTypical trigger
501 Not ImplementedThe server does not support this method or feature at allAn unknown method, a WebDAV method on a server without DAV, an unsupported Transfer-Encoding
405 Method Not AllowedThe method exists, but this URL does not take it; the response must list the allowed ones in an Allow headerPUT or DELETE on a static file, POST to a page that only serves GET
400 Bad RequestThe request itself is malformedInvalid characters in the method, broken headers, Content-Length and Transfer-Encoding together
403 ForbiddenUnderstood, but refused by a ruleA WAF rule or an nginx limit_except block that denies the method

In practice the line is blurry, because servers disagree about which code fits. The same unknown method gets a 405 from nginx, a 501 from Apache and a 400 from Node.js, as the next table shows. The status tells you which software answered at least as much as what went wrong. A 501 is a server-side status like a 500 Internal Server Error, but it is not a crash: the server understood the request well enough to decline it.

What nginx, Apache and others answer

Requestnginx, static filesApache 2.4, static filesPython http.serverNode.js http
Unknown method, e.g. FOO405501, page text FOO not supported for current URL.501400, before your code runs
PUT, DELETE, PROPFIND without DAV405405, The requested method PUT is not allowed for this URL.501Whatever your handler returns
OPTIONS405200 with an Allow header501Whatever your handler returns
A Transfer-Encoding other than chunked501400 when chunked is not the last codingNot checked400 for identity

The nginx and Apache columns follow their source code (nginx’s static and request modules, httpd 2.4’s core, protocol and error page code), read on 21 October 2026. The Python and Node.js columns were checked on Debian 12 with Python 3.11.2 and Node.js 25.7.0. Python’s built-in server only implements GET and HEAD, so everything else is a 501:

Example output · python3 -m http.server 18501 --bind 127.0.0.1 (Debian 12)
$ curl -s -i -X PUT http://127.0.0.1:18501/index.html
HTTP/1.0 501 Unsupported method ('PUT')
Server: SimpleHTTP/0.6 Python/3.11.2
Date: Wed, 21 Oct 2026 19:47:43 GMT
Connection: close
Content-Type: text/html;charset=utf-8
Content-Length: 356

One more rule matters for reading these: when nginx hands a request to an app with proxy_pass or fastcgi_pass, it passes every well-formed method through except TRACE, which nginx always answers with a 405 itself. A 501 behind such a location came from the app, and the app’s own log has the reason.

The usual causes

WebDAV clients on a server without DAV

WebDAV (RFC 4918) adds methods of its own: PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK and UNLOCK. Mapping a web folder as a network drive in Windows Explorer, connecting to a server from the macOS Finder, file sync tools, calendar and contact clients and many backup apps all speak it. Point one at a plain web server and the first PROPFIND gets a 405 or a 501. Either enable DAV on the server (below) or point the client at the app that implements DAV itself, such as a self-hosted cloud or calendar server.

API methods that hit a static location or a dev server

A frontend that sends PUT, PATCH or DELETE to a URL that the web server maps to files, instead of to the API, gets a 405 from nginx and Apache. The 501 variant shows up with minimal servers: a mock backend started with python3 -m http.server refuses every OPTIONS request, and that includes the preflight a browser sends before a cross-origin PUT or JSON POST. The browser then reports a CORS failure, not the 501. The CORS error guide shows how the preflight must be answered.

Proxies, load balancers and WAFs in between

Between the client and your app there may be a CDN, a WAF, a load balancer and a reverse proxy, and any of them can refuse a method it does not know or does not allow. Some older forward proxies and appliances answer unknown methods with a 501 of their own. WAFs usually answer with a 403 instead: the OWASP Core Rule Set, for example, allows only a short list of methods by default. Compare the Server header and the error page with what your own server sends, then skip the layers in front and ask your server directly:

Linux · macOS · bypass the CDN or proxy (203.0.113.10 = your server)
curl -s -i -X PUT --data 'x' \
  --resolve example.com:443:203.0.113.10 https://example.com/api/items/1 | head -n 5

If the direct request works and the normal one gets a 501, the layer in front refused it, and its configuration or its support documentation is the place to fix it.

An unsupported Transfer-Encoding

nginx accepts exactly one request transfer coding, chunked. Per its source code, any other value, such as identity or gzip, chunked, gets a 501, and the reason is logged only at the info level, which the default error log does not record: client sent unknown "Transfer-Encoding". Apache answers a 400 when chunked is not the last coding, as with identity. The senders are usually old HTTP libraries or custom clients. Fix the client: send a Content-Length or plain chunked, and compress the body with Content-Encoding if it must be compressed. To see nginx’s reason, raise the log level for a short test:

/etc/nginx/nginx.conf · temporarily, then set it back
error_log /var/log/nginx/error.log info;

Embedded and development servers

Web interfaces of routers, printers, cameras and other devices often implement GET and POST and nothing else, and so do quick development servers. A 501 from one of them is a statement of fact, not a fault. Use the device’s own app or API, or put a full web server in front of whatever needs more methods.

Fixing it on nginx

For an app behind nginx, make sure the location that receives the request passes it on, and that no limit_except block or static location in front catches it first. For plain file uploads over HTTP, nginx’s own DAV module handles PUT, DELETE, MKCOL, COPY and MOVE. It does not handle PROPFIND, OPTIONS or LOCK, which is what a mapped network drive needs; those come from the third-party dav-ext module, which Debian and Ubuntu package as libnginx-mod-http-dav-ext. Check what your build has:

Debian · Ubuntu
nginx -V 2>&1 | tr ' ' '\n' | grep -i dav
ls /etc/nginx/modules-enabled/ | grep -i dav
nginx · an upload directory that takes PUT and DELETE, with a password
location /upload/ {
    root /var/www;
    dav_methods PUT DELETE MKCOL COPY MOVE;
    create_full_put_path on;
    dav_access user:rw group:r all:r;

    # everyone may read; every other method needs the password
    limit_except GET HEAD {
        auth_basic "upload";
        auth_basic_user_file /etc/nginx/upload.htpasswd;
    }
}
test and reload
sudo nginx -t && sudo systemctl reload nginx

The directory must be writable by the nginx worker user (www-data on Debian and Ubuntu), and large uploads also need client_max_body_size, as the 413 guide explains. The config above is written from nginx.org’s documentation for ngx_http_dav_module and limit_except; run nginx -t before every reload.

Fixing it on Apache

Apache ships WebDAV as mod_dav with the file system provider mod_dav_fs, covering PROPFIND and the other DAV methods. Enable both and switch DAV on for one directory only, behind authentication:

Debian · Ubuntu · Apache
sudo a2enmod dav dav_fs
sudo mkdir -p /var/www/dav && sudo chown www-data:www-data /var/www/dav
sudo htpasswd -c /etc/apache2/webdav.passwd alice
sudo apache2ctl -M | grep -i dav
Apache · inside the HTTPS VirtualHost
<Directory /var/www/dav>
    Dav On
    AuthType Basic
    AuthName "WebDAV"
    AuthUserFile /etc/apache2/webdav.passwd
    Require valid-user
</Directory>
test and reload
sudo apache2ctl configtest && sudo systemctl reload apache2

Two Apache settings produce refusals that look like a missing feature:

  • HttpProtocolOptions RegisteredMethods makes Apache answer 501 to every method that is not registered, already while it parses the request. The default is LenientMethods; a custom method can be allowed with RegisterHttpMethod.
  • <Limit> and <LimitExcept> blocks with Require all denied refuse methods with a 403, not a 501.
Debian · Ubuntu · find either one
sudo grep -rn -E 'HttpProtocolOptions|RegisterHttpMethod|<Limit' /etc/apache2/ /var/www/

Why a fixed 501 can keep coming back

RFC 9110 lists 501 among the status codes a cache may store by heuristic, like 404 and 405, as long as no header says otherwise. A browser or a CDN can therefore keep serving the old 501 after you have fixed the server. Test with curl, which keeps no cache, and purge the CDN for that URL. On error pages you generate yourself, send Cache-Control: no-store.

The HTTP header checker shows the status code and headers from outside your network, which tells you whether a CDN still answers with a stored copy.

Find every 501 in your logs

On a VPS or dedicated server you run every layer yourself, so each 501 is in an access log together with its method. In the default combined log format, the method is field 6 (with the opening quote of the request line, which substr strips) and the status field 9:

Debian · Ubuntu · which methods and paths got a 501
sudo awk '$9 == 501 {print substr($6, 2), $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
# Apache: the same with /var/log/apache2/access.log

A burst of 501s or 405s for methods you never use, from addresses you do not know, is usually a scanner probing for WebDAV or debug methods. It needs no fix beyond keeping those methods switched off.

For search engines, a 501 counts as a server error like any other 5xx. Google’s crawler documentation says 5xx answers make Googlebot slow down, and URLs that keep failing are eventually dropped from the index. Googlebot fetches pages with GET, so a 501 on a normal page is always worth fixing: something in front of the site refuses the most basic request there is.

Frequently asked

What does 501 Not Implemented mean?

The server does not support the functionality the request needs, usually its HTTP method. RFC 9110 reserves 501 for a method the server does not recognise for any resource; a method it knows but does not allow at that URL should get 405 Method Not Allowed. A request with a Transfer-Encoding the server cannot decode can also get a 501.

What is the difference between 501 and 405?

501 says the server does not support the method at all. 405 says it knows the method but this URL does not accept it, and the response must list the allowed methods in an Allow header. Servers differ in practice: an unknown method such as FOO gets 405 from nginx serving a static file, 501 from Apache and 400 from Node.js's built-in HTTP server.

How do I fix a 501 error for WebDAV or PROPFIND?

Enable WebDAV on the server, or route the path to an app that implements it. On Apache, enable mod_dav and mod_dav_fs and set Dav On for one directory behind authentication. nginx's built-in DAV module handles PUT, DELETE, MKCOL, COPY and MOVE but not PROPFIND, which needs the third-party dav-ext module.

Can a visitor fix a 501 error?

Rarely. A 501 is the server's answer, so the fix is on the server or on the proxy in front of it. Clearing the browser cache only helps when an old, cached 501 is shown. If a normal page returns 501 in every browser, report the URL and the time to the site owner.

Related articles

All troubleshooting