What is a 404 Error?
404 means 'page not found'—the server understood your request but couldn't find what you asked for. Here's why they happen and what the other HTTP status codes mean.
Why 404s happen
When you visit a URL, your browser asks a server: “Give me this page.” The server looks for it and responds with a status code.
404 scenarios:
- The page existed but was deleted
- The URL has a typo (
/abuotinstead of/about) - Someone linked to a page that never existed
- The site restructured and old URLs no longer work
- You’re trying to access a resource that requires different permissions
The server isn’t broken—it just can’t find what you asked for.
HTTP status codes explained
404 is part of a larger system. Every HTTP response includes a status code telling you what happened:
Success (2xx) ✅
| Code | Meaning | When you see it |
|---|---|---|
| 200 | OK | Everything worked |
| 201 | Created | You created a new resource (POST succeeded) |
| 204 | No Content | Success, but nothing to return (DELETE succeeded) |
Redirect (3xx) ↪️
| Code | Meaning | When you see it |
|---|---|---|
| 301 | Moved Permanently | Page has a new URL forever |
| 302 | Found (Temporary Redirect) | Page temporarily at different URL |
| 304 | Not Modified | Use your cached version |
Client Error (4xx) ❌
| Code | Meaning | When you see it |
|---|---|---|
| 400 | Bad Request | Your request was malformed |
| 401 | Unauthorized | You need to log in |
| 403 | Forbidden | You’re logged in but don’t have permission |
| 404 | Not Found | Resource doesn’t exist |
| 405 | Method Not Allowed | Wrong HTTP method (GET vs POST) |
| 429 | Too Many Requests | You hit a rate limit |
Server Error (5xx) 💥
| Code | Meaning | When you see it |
|---|---|---|
| 500 | Internal Server Error | Server crashed |
| 502 | Bad Gateway | Server got bad response from upstream |
| 503 | Service Unavailable | Server overloaded or down for maintenance |
| 504 | Gateway Timeout | Upstream server took too long |
The codes you’ll see most as a vibecoder
200: Your API call worked. Parse the response and use the data.
400: Your request body is malformed. Check your JSON syntax, required fields, and data types.
401: Your API key is missing or invalid. Check your authentication headers.
403: Your API key is valid but doesn’t have permission for this action. Check your account settings or plan limits.
404: The endpoint or resource doesn’t exist. Check the URL, check the API docs.
429: You hit the rate limit. Slow down, implement backoff, or upgrade your plan.
500: The server broke. Usually not your fault—try again later or check the service’s status page.
Debugging API errors
When your API call fails, the status code tells you where to look:
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ message: 'Hello' })
});
if (!response.ok) {
console.log('Status:', response.status);
const error = await response.json();
console.log('Error:', error);
// Now you know:
// 400 → Check your request body
// 401 → Check your API key
// 404 → Check the URL
// 429 → Slow down
// 500 → Server problem, retry later
}Handling errors in your app
Good error handling means showing users helpful messages, not cryptic codes:
async function callAI(prompt) {
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt })
});
if (response.status === 429) {
return { error: "We're getting too many requests. Please wait a moment." };
}
if (response.status === 401) {
return { error: "There's a problem with our AI connection. We're on it." };
}
if (response.status >= 500) {
return { error: "The AI service is temporarily unavailable. Try again soon." };
}
if (!response.ok) {
return { error: "Something went wrong. Please try again." };
}
return await response.json();
}Creating custom 404 pages
When users hit a 404 on your site, don’t show them a blank error. Help them:
Next.js:
// app/not-found.tsx
export default function NotFound() {
return (
<div>
<h1>Page not found</h1>
<p>The page you're looking for doesn't exist.</p>
<a href="/">Go home</a>
</div>
);
}Express:
// Put this LAST, after all other routes
app.use((req, res) => {
res.status(404).json({
error: 'Not found',
message: `No route matches ${req.method} ${req.path}`
});
});404 vs. other “not working” situations
| Symptom | Likely cause | Status code |
|---|---|---|
| Page not found | Bad URL or deleted content | 404 |
| “Access denied” | Not logged in | 401 |
| “Permission denied” | Logged in but not authorized | 403 |
| Page loads but empty | Successful request, no data | 200 with empty response |
| Page never loads | Network issue, server down | No response (timeout) |
| Page loads with error message | Server crashed while processing | 500 |
The developer tools trick
When something isn’t working:
- Open browser DevTools (F12 or Cmd+Opt+I)
- Go to the Network tab
- Refresh the page or retry the action
- Look at the status codes
This shows you exactly what’s happening at the HTTP level—which requests succeeded, which failed, and why.
Further reading
- What is an API? : How HTTP requests work
- What is rate limiting? : Understanding 429 errors
- What is localhost? : Where these errors happen during development
Frequently asked questions
Why is it called 404?
Is a 404 error my fault or the server's fault?
How do I create a custom 404 page for my app?
not-found.tsx file. In Express, add a catch-all route at the end. The goal is showing users a helpful page instead of a generic error.