Skip to content

404 Not Found

What is HTTP 404 Not Found?

404 Not Found
When you type a website address, your computer asks that website's computer to s...
HTTP 404 Not Found status code illustration

Explain Like I’m 3

You’re looking for something, but it’s not there! Like when you open a toy box to find your favorite toy, but it’s not inside. The thing you want is missing!

Example: You try to open a door to a room, but there’s no room behind it - just a wall!

Explain Like I’m 5

When you type a website address, your computer asks that website’s computer to show you a page. A 404 error means the website computer looked everywhere but couldn’t find that page. It’s like going to the library and asking for a book, but the librarian tells you that book doesn’t exist in their library.

Example: You visit a website and click a link to see pictures of cats. But the website says ‘404 Not Found’ because someone deleted those cat pictures or the link is wrong.

Jr. Developer

HTTP 404 means the server couldn’t find the resource you requested at that URL. This usually happens when a page has been deleted, moved without a redirect, or the URL was typed incorrectly. The server successfully received your request and processed it, but the specific resource at that path doesn’t exist. It’s one of the most common errors you’ll encounter while building websites.

Example: A user clicks an old bookmark to yoursite.com/blog/old-post, but you’ve since deleted that blog post without setting up a redirect. The server returns 404 because nothing exists at that path anymore.

Code Example

// Express.js handling 404
app.get('/users/:id', async (req, res) => {
const user = await db.findUser(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
});

Crash Course

404 Not Found indicates the server cannot find the requested resource. Unlike 410 Gone (which indicates permanent removal), 404 doesn’t specify whether the absence is temporary or permanent. This is the appropriate response when a URL path doesn’t match any server resources, whether due to typos, deleted content, or broken links. The 404 status is cacheable by default unless specified otherwise via cache headers. Servers should include a helpful error page explaining the situation and suggesting next steps. Custom 404 pages significantly improve user experience compared to default server error pages.

Example: An e-commerce site’s product at /products/12345 is deleted from inventory. Rather than showing an error, the server returns 404 with a custom page saying ‘This product is no longer available’ and suggests similar products.

Code Example

// Custom 404 handling with helpful response
app.use((req, res, next) => {
res.status(404).json({
error: 'Resource not found',
path: req.path,
suggestions: [
'/api/products',
'/api/users',
'/api/docs'
],
message: 'Check the URL or browse our API documentation'
});
});

Deep Dive

The 404 Not Found status code, defined in RFC 9110 Section 15.5.5, indicates that the origin server did not find a current representation for the target resource or is unwilling to disclose that one exists. This semantic ambiguity is intentional - servers may return 404 for resources that exist but shouldn’t be revealed to unauthorized clients, though 403 Forbidden is more semantically appropriate for known resources. The status is cacheable by default unless cache-control directives specify otherwise. Unlike 410 Gone, 404 makes no assertion about permanence, making it suitable for both temporarily unavailable resources and truly non-existent ones.

Technical Details

From a protocol perspective, 404 responses should include an entity containing an explanation of the error situation. The response may include a Retry-After header for temporarily missing resources, though this is rare in practice. Caching behavior follows standard HTTP caching rules: heuristic expiration may be applied by caches in the absence of explicit directives. Security considerations include the risk of information disclosure - responding with 404 vs. 403 can reveal resource existence. Some applications intentionally use 404 to hide protected resources from enumeration attacks, though this provides security through obscurity rather than true protection.

The distinction between 404 and related status codes is protocol-significant: 404 indicates the resource doesn’t exist at this URI, 410 indicates it once existed but is permanently gone (and the server knows this), 403 indicates it exists but access is denied, and 301/302 indicate it exists elsewhere. Proper use of these codes enables clients to make appropriate decisions about retry logic, caching, and user messaging.

Modern SPA (Single Page Application) architectures often complicate 404 handling. The server may return 200 OK with the index.html shell, leaving the client-side router to determine and display 404 states. This violates REST principles and breaks HTTP caching, but has become common practice. A more RESTful approach involves server-side routing that returns genuine 404 responses with appropriate content, or hybrid rendering strategies.

Code Example

// Production-grade 404 handling with logging and metrics
const notFoundHandler = (req, res, next) => {
// Log 404s for monitoring broken links
logger.warn('404 Not Found', {
path: req.path,
method: req.method,
referer: req.get('Referer'),
userAgent: req.get('User-Agent'),
ip: req.ip
});
// Increment metrics
metrics.increment('http.404.count', {
path: req.path,
method: req.method
});
// Set appropriate cache headers
res.set({
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Content-Type': 'application/json'
});
// Return structured error response
res.status(404).json({
error: {
code: 'RESOURCE_NOT_FOUND',
message: 'The requested resource does not exist',
path: req.path,
timestamp: new Date().toISOString(),
requestId: req.id
}
});
};
app.use(notFoundHandler);

Frequently Asked Questions

What's the difference between 404 Not Found and 410 Gone?

404 means the server can't find the resource but doesn't know if it's temporary or permanent. 410 explicitly states the resource is permanently gone and won't come back. Use 410 when you intentionally removed something and want search engines to stop crawling it faster.

Should I return 404 or 403 for resources that exist but the user can't access?

Technically, 403 Forbidden is correct when a resource exists but access is denied. However, returning 404 prevents unauthorized users from discovering which resources exist on your server. This is a security vs. semantics trade-off - many APIs use 404 to avoid resource enumeration attacks.

Are 404 responses cached by browsers?

Yes, 404 responses are cacheable by default according to HTTP specifications. However, most browsers and proxies use conservative caching policies for error responses. You can control this with Cache-Control headers - use 'no-cache' if the resource might appear later, or allow caching if you're confident it won't exist.

Why does my SPA return 200 instead of 404 for missing pages?

Many Single Page Applications (SPAs) serve index.html for all routes (returning 200 OK), then let JavaScript determine if the route exists. While convenient for client-side routing, this breaks HTTP semantics and SEO. Better approaches include server-side rendering or configuring your server to return actual 404s for non-existent routes.

How do I create a custom 404 page?

Configure your web server or application framework to serve a custom HTML page or JSON response when returning 404 status. Make it helpful: explain what happened, suggest navigation options, include a search box, and maintain your site's design. Custom 404 pages improve user experience and can reduce bounce rates.

Common Causes

  • URL was mistyped or contains a typo in the path
  • Resource was deleted or moved without setting up a redirect
  • Broken or outdated links from external sites or old bookmarks
  • Incorrect routing configuration in the web server or application
  • File or directory permissions preventing the server from accessing the resource
  • Case-sensitive file systems where /Page.html differs from /page.html

Implementation Guidance

  • Verify the URL is correct and matches the actual file path on the server
  • Set up 301 redirects for moved or renamed resources using .htaccess or server config
  • Check routing configuration in your web framework (Express, Django, Rails, etc.)
  • Restore deleted files from backups if they were removed accidentally
  • Review and fix .htaccess rewrite rules that might be blocking valid requests
  • Implement a custom 404 page that helps users find what they’re looking for
  • Use tools like Google Search Console to identify and fix broken links
  • For SPAs, configure server to handle client-side routing correctly

Comments