DEVESSENTIALS

HTTP 404 Not Found

404 is the most familiar status code: nothing is available at this URL. RFC 9110 notes that it doesn't say whether the absence is temporary or permanent; use 410 Gone when you know a resource was removed for good.

4xx · Client errorRFC 9110 §15.5.5

404 Not Found

The server has no current representation of the target resource, or won't say whether one exists.

Who fixes it: Either side. A mistyped URL is the client's problem. Broken internal links, missing redirects and SPA routing gaps are the site's.

What 404 means

A 404 is cacheable by default, so a CDN may keep serving a 404 for a page you've just published until the cached error expires.

Servers may also return 404 to hide a resource the client isn't allowed to see, instead of 403.

Source: RFC 9110 §15.5.5.

Common causes

  • A typo or an outdated link, including links from other sites to URLs you renamed without a redirect.
  • Single-page apps: client-side routes like /dashboard/settings work while navigating but 404 on refresh, because the web server looks for a file at that path.
  • Case sensitivity: /About and /about are different on Linux servers and S3, though they may both work on a case-insensitive Mac during development.
  • Trailing slash mismatches (/docs/ vs /docs), especially on static hosting.
  • A wrong path prefix behind a reverse proxy: in nginx, proxy_pass with or without a trailing slash changes the path the backend receives.
  • APIs: a wrong version prefix, a record ID that doesn't exist, or an unsupported method. Express answers Cannot POST /x with 404 rather than 405.
  • The deploy didn't include the file: wrong build output directory, or the file was ignored.
  • A CDN serving a cached 404 from before the page existed.

How to fix a 404

Check what the server actually received

Compare a failing URL with a working one, then check the backend's access log for the path it saw, which may differ from what the browser requested.

curl -sI https://example.com/dashboard/settings
HTTP/2 404

curl -sI https://example.com/
HTTP/2 200

nginx: fallback for single-page apps

Serve the file if it exists, otherwise hand the route to the SPA. Keep real 404s for missing assets so broken script URLs don't return HTML.

location / {
    root /var/www/app/dist;
    try_files $uri $uri/ /index.html;
}

location /assets/ {
    root /var/www/app/dist;
    try_files $uri =404;
}

nginx: the proxy_pass trailing slash

With a URI part on proxy_pass (even just /), nginx replaces the matched location prefix. Without one, the original path is passed through.

# Request: GET /api/users

# Option A: backend receives /api/users
location /api/ {
    proxy_pass http://127.0.0.1:3000;
}

# Option B: backend receives /users
location /api/ {
    proxy_pass http://127.0.0.1:3000/;
}

Express: a JSON 404 for unknown API routes

Register it after all other routes.

app.use('/api', (req, res) => {
  res.status(404).json({ error: 'not_found', path: req.originalUrl });
});

Next.js

notFound() renders app/not-found.tsx with a 404 status. With dynamicParams = false, any path not returned by generateStaticParams is a 404 automatically.

import { notFound } from 'next/navigation';

const product = await getProduct(id);
if (!product) notFound();

Headers that matter with 404

Cache-Control
Give 404s a short max-age (or no-store) so a newly published page doesn't stay hidden behind a cached 404 on your CDN.

404 vs similar status codes

  • 410 Gone: The resource existed and was removed deliberately. A clearer signal for clients and crawlers.
  • 403 Forbidden: The resource exists but you may not have it. Servers sometimes answer 404 instead to hide it.
  • 405 Method Not Allowed: The URL exists but not for that HTTP method.
  • 301 Moved Permanently: If the content moved, redirect instead of returning a 404.

SEO impact of 404

404s don't hurt a site's rankings in general; Google expects them for URLs that never existed or were removed. What matters: return a real 404 status rather than a 200 "not found" page (soft 404); 301-redirect removed pages that have a clear replacement and valuable backlinks, but don't redirect everything to the homepage; use 410 if you want removal to read as intentional (Google treats 404 and 410 almost identically); and fix broken internal links, which waste crawl budget.

Related status codes

Looking for another code? Search the full HTTP status codes list, or read which code your API should return in the REST API status codes guide.

Learn more

Browse all developer guides →

Frequently Asked Questions

Do 404 errors hurt SEO?▾

Not by themselves. Google says 404s for pages that don't exist are normal and don't affect how the rest of the site ranks. The problems are soft 404s, broken internal links, and removed pages with valuable backlinks that should have been redirected.

What is a soft 404?▾

A page that tells users it's not found, or is nearly empty, but returns 200 OK. Search engines flag it in Search Console because the status code says the page exists. Fix it by returning a real 404 or 410, or by adding real content.

Should I use 404 or 410 for deleted pages?▾

410 Gone says the removal is deliberate and permanent; 404 just says nothing is there. For search engines the difference is small. For APIs, 410 is a useful hint that clients should delete their cached references.

Why does my React or Vue app return 404 when I refresh the page?▾

The server looks for a file at that path, but the route only exists in the client-side router. Configure a fallback to index.html (try_files in nginx, a rewrite on Vercel or Netlify), or use a framework with server rendering.