Skip to main content
TF
9 min readArticle

HTTP Status Codes Explained — What 200, 404, and 500 Mean

TF
ToolsFuel Team
Web development tools & tips
Digital dashboard displaying data metrics and analytics

Photo by Luke Chesser on Unsplash

The Three-Digit Codes That Run the Internet

Every time your browser loads a page, fetches an image, or submits a form, the server sends back a three-digit number before anything else. That number is an HTTP status code, and it tells the client (your browser, your API client, your fetch call) what happened with the request.

I spent my first year as a developer only knowing three of them: 200 means good, 404 means not found, 500 means something broke. That's enough to get by, but it's like knowing three words in a language — you can survive but you'll miss a lot of context.


There are roughly 60 defined HTTP status codes across five categories. You don't need to memorize all of them. I'm going to focus on the ones that actually show up in real development work — the codes you'll see in your browser's Network tab, in your API logs, and in your error monitoring dashboard. Maybe fifteen codes total that cover 99% of what you'll encounter.

The Five Categories (and What the First Digit Means)

Smartphone displaying code and technical data on screen

Photo by Rodion Kutsaiev on Unsplash

HTTP status codes are grouped by their first digit:

- **1xx — Informational**: The server received your request and is still processing it. You'll rarely see these directly. - **2xx — Success**: Your request worked. The server did what you asked. - **3xx — Redirection**: The thing you asked for is somewhere else. Follow the redirect. - **4xx — Client Error**: You (the client) did something wrong. Bad URL, missing auth, invalid data. - **5xx — Server Error**: The server broke. It's not your fault (usually).


This grouping is actually useful for debugging. If you're getting 4xx errors, the problem is in your request — check the URL, headers, authentication, or request body. If you're getting 5xx errors, the problem is on the server — check logs, database connections, and server health.


I've met developers who didn't know this categorization and would spend thirty minutes debugging their API client code when the real issue was a 502 from a crashed backend. Knowing the first digit saves time.

2xx Success Codes You Should Know

**200 OK** — The most common response on the internet. It means your request succeeded and the server is returning the data you asked for. GET requests return the resource, POST requests return the created resource or a confirmation. Every time a page loads successfully, dozens of 200 responses are flying around.

**201 Created** — The server created a new resource as you requested. You'll see this after successful POST requests when creating records — a new user account, a new blog post, a new order. It's more specific than 200 and it's what your REST API should return after creating something. The response usually includes the newly created resource and a Location header pointing to its URL.


**204 No Content** — Success, but there's nothing to send back. Common for DELETE requests (the resource is gone, there's nothing to return) and PUT/PATCH requests where the client doesn't need the updated resource back. If you've ever wondered why a successful DELETE returns an empty body — that's 204 doing its job.


**206 Partial Content** — The server is sending only part of the resource, usually because the client requested a specific range. You'll see this when streaming video or downloading large files — the browser requests chunks of the file rather than the whole thing at once. If you're building a file download feature or a video player, you'll encounter 206 in your network logs.


Most of the time, 200 is all you need to check for. But if you're building a REST API, using the right 2xx code (201 for creation, 204 for deletion) makes your API more predictable for consumers. I've debugged API clients that broke because they expected a response body after a DELETE and got an empty 204 instead.

3xx Redirects — Where Things Get Tricky

**301 Moved Permanently** — This resource has permanently moved to a new URL. Browsers (and search engines) should update their bookmarks and links. This is the one you use when you're restructuring your site's URLs and you want Google to transfer the old page's ranking to the new URL. It's also the correct redirect for HTTP-to-HTTPS upgrades.

**302 Found** — A temporary redirect. The resource is temporarily at a different URL, but clients should keep using the original URL for future requests. Login flows use this a lot — you're redirected to the login page, then redirected back to where you were going. The key difference from 301: search engines won't transfer ranking, and browsers won't cache the redirect.


**304 Not Modified** — The resource hasn't changed since you last requested it. The server is telling your browser to use its cached copy instead of downloading everything again. This is how browser caching works at the HTTP level — the browser sends an `If-Modified-Since` or `If-None-Match` header, and the server responds with 304 if the content is still fresh. You'll see tons of 304s in your Network tab for static assets like images, CSS, and JavaScript files.


**307 Temporary Redirect** and **308 Permanent Redirect** — These are the modern replacements for 302 and 301 respectively, with one important difference: they preserve the HTTP method. A 301 or 302 might change a POST request to a GET during the redirect (browsers historically did this). A 307/308 guarantees the method stays the same. If you're redirecting API endpoints that receive POST data, use 307 or 308 to be safe.


The 301 vs 302 distinction is something I got wrong for years. I'd use 302 for everything because it "worked" — but I was accidentally telling search engines that my URL changes were temporary, which hurt SEO. If the URL change is permanent, use 301. If it's temporary (maintenance page, A/B testing), use 302. When in doubt about how URL changes affect search rankings, understanding
how CORS and request routing works helps fill in the picture.

4xx Client Errors — When It's Your Fault

**400 Bad Request** — The server can't understand your request because it's malformed. This usually means invalid JSON in the request body, missing required fields, or a query parameter in the wrong format. When your API returns 400, the response body should explain exactly what's wrong — "email field is required" or "date must be in ISO 8601 format." If it just says "Bad Request" with no details, that's a bad API.

**401 Unauthorized** — You're not authenticated. The server doesn't know who you are because you didn't include credentials, or your credentials are invalid. Despite the name, this is about *authentication* (proving who you are), not *authorization* (having permission). If your JWT is expired or your API key is wrong, you'll get 401.


**403 Forbidden** — You're authenticated but you don't have permission to access this resource. The server knows who you are, but you're not allowed. An admin-only endpoint returning 403 to a regular user is correct behavior. The distinction between 401 and 403 matters — 401 means "log in first," 403 means "you're logged in but you can't do this."


**404 Not Found** — The most famous HTTP status code. The URL you requested doesn't exist on this server. It could be a typo, a deleted page, or a changed URL structure. For APIs, 404 means the specific resource doesn't exist — `GET /users/99999` when user 99999 doesn't exist.


**405 Method Not Allowed** — The URL exists, but not for the HTTP method you used. You sent a DELETE to an endpoint that only accepts GET and POST. The response includes an Allow header listing which methods the endpoint does accept.


**409 Conflict** — The request conflicts with the current state of the server. Common in concurrent editing scenarios — two users trying to update the same record simultaneously, or trying to create a resource that already exists with a unique constraint.


**422 Unprocessable Entity** — The request is well-formed (it's valid JSON, right content type) but semantically wrong. The server understands your request but can't process it because the data doesn't make sense — like setting an end date before the start date, or providing a negative price. Some APIs use 400 for this; some use 422. Both are acceptable.


**429 Too Many Requests** — Rate limiting. You've sent too many requests in a given time window. The response usually includes a `Retry-After` header telling you how long to wait. If you're hitting third-party APIs and getting 429s, implement exponential backoff in your retry logic.


Most 4xx errors in production come from 404s (broken links, typos) and 401s (expired tokens). If you're seeing a lot of 400s, your client-side validation probably isn't catching bad input before it reaches the server.

5xx Server Errors — When It's Not Your Fault

Earth from space at night showing illuminated connected networks

Photo by NASA on Unsplash

**500 Internal Server Error** — The generic "something went wrong on the server" code. An unhandled exception, a null pointer, a database query that threw an error — anything that crashes the request handler produces a 500. It's the server equivalent of a crash. If you're getting 500s from your own API, check the server logs — the HTTP response rarely contains the real error message for security reasons.

**502 Bad Gateway** — The server you're talking to (usually a reverse proxy like Nginx or a load balancer) tried to forward your request to an upstream server, and that upstream server returned an invalid response or didn't respond at all. In practice, 502 usually means your application server has crashed or isn't running. If you're deploying to a platform like Vercel or AWS and see 502s, check whether your function timed out or your container failed to start.


**503 Service Unavailable** — The server is temporarily unavailable, usually due to maintenance or being overloaded. Unlike 500 (unexpected crash), 503 means the server knows it can't handle requests right now and is telling you explicitly. A well-configured server returns a Retry-After header with 503 so clients know when to try again.


**504 Gateway Timeout** — Similar to 502, but specifically the upstream server took too long to respond. Your reverse proxy or load balancer waited for the application server to respond, hit its timeout limit, and gave up. This often means a slow database query, a hanging external API call, or a function that ran longer than the configured timeout.


Here's a debugging pattern I use: if the error is intermittent, it's usually 502 or 504 (resource exhaustion, timeouts). If it's consistent, it's usually 500 (a code bug). If it only happens under load, it's usually 503 (capacity issue). That heuristic has saved me a lot of time.


When you're working with APIs and encoding data for requests, it helps to understand
URL encoding too — malformed URLs are a common cause of unexpected 400 and 404 responses, especially when query parameters contain special characters.

Quick Reference Table and Where to Look Things Up

Here's my personal cheat sheet — the codes I actually use or encounter regularly:

| Code | Name | When You'll See It | |------|------|-------------------| | 200 | OK | Successful request | | 201 | Created | Resource created (POST) | | 204 | No Content | Successful delete | | 301 | Moved Permanently | URL changed, update links | | 302 | Found | Temporary redirect | | 304 | Not Modified | Use cached version | | 400 | Bad Request | Malformed request data | | 401 | Unauthorized | Not authenticated | | 403 | Forbidden | No permission | | 404 | Not Found | URL doesn't exist | | 429 | Too Many Requests | Rate limited | | 500 | Internal Server Error | Server crash | | 502 | Bad Gateway | Upstream server down | | 503 | Service Unavailable | Server overloaded | | 504 | Gateway Timeout | Upstream too slow |


The full official list is in
RFC 9110, which replaced the older RFC 7231 in 2022. MDN also has an excellent reference page that's easier to read and includes browser-specific notes.

If you're building APIs and want to inspect request/response data more easily, ToolsFuel has
developer tools for formatting JSON responses and decoding URL-encoded parameters — both are things I end up doing constantly when debugging HTTP issues.

Frequently Asked Questions

What is the difference between 401 and 403 status codes?

401 Unauthorized means you're not authenticated — the server doesn't know who you are because you didn't provide valid credentials (missing or expired token, wrong API key). 403 Forbidden means you're authenticated but don't have permission to access the resource — the server knows who you are but you're not allowed. Think of 401 as 'show me your ID' and 403 as 'I know who you are, but you can't go in here.' In practice, 401 should trigger a login flow while 403 should show a permissions error.

Why do I keep getting 502 Bad Gateway errors?

A 502 means the server acting as a gateway or proxy received an invalid response from an upstream server. In plain terms: the web server (Nginx, a CDN, or a cloud platform) forwarded your request to your application code, and the application either crashed, returned garbage, or didn't respond at all. Common causes include an application server that's not running, a deployment that failed, memory exhaustion causing the process to die, or a function that crashes before returning a response. Check your application logs — the 502 itself won't tell you the real error.

What's the difference between 301 and 302 redirects for SEO?

A 301 tells search engines the page has permanently moved — they should transfer the old page's ranking signals to the new URL and stop crawling the old one. A 302 says the redirect is temporary — search engines keep the old URL in their index and don't transfer ranking. If you're permanently changing your URL structure, 301 is correct. If you're temporarily sending users elsewhere (maintenance page, A/B test), 302 is correct. Using 302 when you mean 301 can hurt your SEO because Google won't consolidate the ranking signals to your new URL.

How do I return the right HTTP status code in my API?

Match the code to what actually happened. Created a resource? Return 201. Deleted something? Return 204. Client sent bad data? Return 400 with an error message explaining what's wrong. Resource not found? Return 404. Server crashed? Your framework should automatically return 500, but add error handling so you can return more specific codes. The biggest mistake I see is APIs that return 200 for everything and put the actual error in the response body — this breaks standard HTTP client libraries and makes debugging harder.

What does 429 Too Many Requests mean and how do I handle it?

429 means you've hit a rate limit — you've sent more requests than the server allows in a given time window. The response usually includes a Retry-After header telling you how many seconds to wait before retrying. The correct way to handle it is implementing exponential backoff: wait the specified time, then retry. If it fails again, wait longer (double the delay each time). Don't retry immediately in a loop — that'll just get you rate-limited harder or banned entirely. Most API client libraries have built-in retry logic you can configure.

Is a 404 error bad for SEO?

A few 404s are normal and won't hurt your site. Google expects some pages to be deleted or moved over time. What hurts SEO is having many 404 errors from pages that should exist — broken internal links, deleted pages without redirects, or URLs that changed without setting up 301 redirects. Check Google Search Console's Coverage report regularly for crawl errors. If an old URL still gets traffic or has backlinks, set up a 301 redirect to the closest equivalent page. Don't 301 everything to the homepage though — that's considered a soft 404 and Google will eventually ignore it.

Try ToolsFuel

23+ free online tools for developers, designers, and everyone. No signup required.

Browse All Tools