breakitdown

404 Not Found

Answer

404 Not Found means the server has no resource at the requested URL, or chooses not to say it has one. The request reached a server that understood it; the path is the problem.

404
Not Found RFC 9110 §15.5.5

The server has nothing at this URL, or will not admit that it does.

The most common error on the web. It does not say whether the absence is temporary or permanent; use 410 if you know a resource is gone for good. When a route you just deployed returns 404, check the URL path prefix, trailing slashes, case sensitivity and whether the proxy forwards that path to the right backend.

410
Gone RFC 9110 §15.5.11

The resource used to exist here, has been removed on purpose, and will not come back.

Stronger than 404: it tells clients and search engines to drop the URL. Use it for deleted content or retired API versions. Responses are cacheable by default.

Explained

A 404 says nothing about permanence. If a page was removed on purpose and will not return, 410 Gone is a clearer signal; search engines tend to drop 410 URLs from their index sooner.

Servers also use 404 to hide resources from callers without access, so in an API a 404 can mean "forbidden" in disguise. Check permissions as well as the path.

For single-page apps, a hard reload of a client-side route such as /settings returns 404 unless the web server is told to serve index.html for unknown paths (in nginx, try_files $uri /index.html;). Do the opposite for real missing pages: a page that says "not found" but returns 200 is a soft 404, which search engines flag as an error.

How to debug it

  1. Compare the exact path the server received (in its access log) with the route you expect: watch trailing slashes, letter case and URL encoding.
  2. If the app sits behind a proxy under a prefix such as /api, check whether the proxy strips or keeps that prefix. In nginx, a trailing slash on proxy_pass http://app/; replaces the matched location prefix.
  3. Confirm the new code is actually deployed and the request reaches the instance you think it does.
  4. For a static file, check that it exists in the document root the server uses, not just in your build output.
  5. For an API, check whether the 404 is the framework's default route-not-found response or your code reporting a missing record; their bodies usually differ.

Gotchas

Related explainers

← All HTTP status codes