curl: (22) The requested URL returned error: 404 means the server answered with HTTP 404 Not Found and you ran curl with -f (--fail), which turns an HTTP error status into curl exit code 22. Fix the path in the URL; the server is up and answering.

Without -f, the same request exits with 0 and prints the server's error page, so -f is what lets a script notice the 404. Add -w '%{http_code}' to see the status either way.

The error

$ curl -sS -f http://web:8080/missing.html
curl: (22) The requested URL returned error: 404
exit=22

Why it happens

The server on web:8080 was python3 -m http.server serving a folder that holds index.html and no missing.html. It answered 404. With -f, curl printed the code 22 line and exited with 22. The connection, the name lookup and the server were all fine here: the number at the end of the message is the HTTP status the server sent, and the code in brackets is curl's own exit code for it. A 404 therefore points at the path part of the URL, not at the network.

The same request without -f did not fail as far as the exit code goes:

$ curl -sS http://web:8080/missing.html > /dev/null
exit=0
$ curl -sS http://web:8080/missing.html | head -3
<!DOCTYPE HTML>
<html lang="en">
    <head>
exit=0
$ curl -sS -o /dev/null -w '%{http_code}\n' http://web:8080/missing.html
404
exit=0

Without -f, curl printed the server's HTML error page and exited with 0, so a script that checks only the exit code would carry on as if the download had worked. The head -3 run shows the first lines of that page (its exit=0 is the pipeline's). -w '%{http_code}\n' printed the status, 404, while the exit code stayed 0.

The fix

$ curl -sS -f -o /dev/null -w '%{http_code}\n' http://web:8080/index.html
200
exit=0

With the path corrected to a file that exists, the same -f request returned 200 and exit code 0. Keep -f in scripts: the code 22 is what tells the script the download did not happen.

How it was reproduced

Reproduced inside ubuntu:24.04 containers on one user-defined Docker network on Docker engine 29.9.3, with curl 8.5.0 from apt in the client. The server container, alias web, ran python3 -m http.server 8080 --directory /srv/www (Python 3.12.3) with an index.html in that folder. The containers and the network were removed afterwards.

Frequently asked

What does curl: (22) The requested URL returned error: 404 mean?
The server answered 404 Not Found and curl ran with -f or --fail, which makes an HTTP error status exit with code 22.
Why does curl return exit code 0 on a 404?
Without -f, curl treats the error page as a normal response. In this test it printed the HTML error page and exited with 0.
How do I get the HTTP status code with curl?
Use -w '%{http_code}\n', here together with -o /dev/null to drop the body. Here it printed 404 for the missing file and 200 for index.html.

If the server cannot be reached at all, see curl: (7) Failed to connect. More decoded errors in the Fixes category.