HTTP Status Codes
Every HTTP status code with what it means and when to use it.
About this tool
Look up any HTTP status code by number or name. Each one has a plain description and a note on when to return it, which helps when designing an API or reading a failing request.
How to use it
- Type a status code, like 404, or a word, like redirect or rate limit.
- Filter by class: 1xx informational, 2xx success, 3xx redirects, 4xx client errors, 5xx server errors.
- Read what each code means and when to return it.
Questions
- What is the difference between 401 and 403?
- 401 means the client is not authenticated, for example the token is missing or expired. 403 means the client is authenticated but not allowed to do this.
- Should validation errors return 400 or 422?
- Both are used. A common convention is 400 for requests that can’t be parsed and 422 for well-formed requests whose values fail validation.
- When should I use 301 versus 308?
- Both are permanent redirects. With 301, browsers may turn a POST into a GET; 308 guarantees the method and body are kept. For plain page moves, 301 is fine.
- What is the difference between 502 and 504?
- Both come from a proxy or load balancer. 502 means the server behind it returned an invalid response or crashed; 504 means it didn’t respond in time.
- What does status code 0 mean?
- It isn’t an HTTP status. Browsers report 0 when no response reached the script: the request was blocked by CORS, cancelled, hit a network or DNS error, or was blocked as mixed content. Check the browser console and the Network tab for the real reason.
- Is it OK to return 404 instead of 403?
- Yes. RFC 9110 allows a server to answer 404 when it doesn’t want to reveal that a resource exists to someone who may not see it. GitHub does this for private repositories. Use 403 when the client may know the resource exists but isn’t allowed to access it.
- Which status codes can be cached by default?
- Under RFC 9110, responses with 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414 and 501 can be cached heuristically when no Cache-Control or Expires header says otherwise. So a CDN may keep serving a 404 for a while. Send explicit cache headers to control this.
What are HTTP status codes?
Every HTTP response starts with a three-digit status code that tells the client how the request went. The codes and their meanings are defined in RFC 9110, with a few added by other RFCs, such as 429 Too Many Requests from RFC 6585. The first digit sets the class: 1xx informational, 2xx success, 3xx redirection, 4xx client error and 5xx server error. A client that doesn’t know a code treats it like the x00 code of its class.
The class is what most software acts on. Browsers follow 3xx redirects, retry logic usually retries some 5xx responses but never most 4xx ones, and monitoring counts 5xx as errors on your side. The reason phrase after the number, like “Not Found”, is informational only, and HTTP/2 drops it entirely. That is why choosing the right number matters more than the message you send with it.
Which HTTP status code should my API return?
Start with the common cases. Return 200 for a successful read or update with a body, 201 with a Location header when a POST creates something, and 204 when there is nothing to send back, such as after a DELETE. Use 202 when the work is queued and finishes later. Avoid returning 200 with an error message in the body: clients, caches and monitoring tools all trust the status code first.
For errors, separate the client’s fault from yours. Use 400 for malformed input, 404 when the resource doesn’t exist, 409 for conflicts like a duplicate email address, and 429 with a Retry-After header for rate limits. Keep 5xx for failures on the server side, and log the details instead of returning stack traces. A consistent error body, such as Problem Details from RFC 9457, helps clients show useful messages.
How to check the status code of a request
In the browser, open the developer tools, switch to the Network tab and reload the page. The Status column shows the code of every request, including failed fetch calls made by scripts. On the command line, curl -i prints the status line and response headers before the body, curl -I sends a HEAD request to show only the headers, and adding -L follows redirects so you see every hop.
When a code surprises you, find out who sent it. A 502, 503 or 504 often comes from nginx, a load balancer or a CDN rather than your app, so check the Server header and the proxy logs. A 404 on a route you know exists usually means a wrong base path or a trailing slash mismatch, while 405 means the path exists but not for that method. The curl Converter helps rebuild the failing request.
All HTTP status codes
Every status code with what it means and when to return it, grouped by class.
Informational (1xx)
| Code | Name | Meaning | When to use |
|---|---|---|---|
| 100 | Continue | The server got the request headers; the client should send the body. | Sent automatically when a client asks with Expect: 100-continue. |
| 101 | Switching Protocols | The server is switching to the protocol the client asked for. | Upgrading a connection to WebSocket. |
| 103 | Early Hints | Preliminary headers so the browser can start preloading. | Send Link headers for CSS and fonts while the page is still being built. |
Success (2xx)
| Code | Name | Meaning | When to use |
|---|---|---|---|
| 200 | OK | The request succeeded. | Default for a successful GET, or a POST that returns a result. |
| 201 | Created | A new resource was created. | After a POST that creates something. Include a Location header pointing to it. |
| 202 | Accepted | The request was accepted but hasn’t been processed yet. | Queued or background jobs. Return a way to check progress. |
| 204 | No Content | Success, with nothing to send back. | A DELETE or PUT that doesn’t return a body. |
| 206 | Partial Content | Only part of the resource is returned. | Answering a Range request, for video streaming or resumable downloads. |
Redirection (3xx)
| Code | Name | Meaning | When to use |
|---|---|---|---|
| 301 | Moved Permanently | The resource has a new permanent URL. | Old URLs after a site restructure. Browsers and search engines remember it. |
| 302 | Found | The resource is temporarily at another URL. | Short-lived redirects. Clients may change POST to GET; prefer 303 or 307 to be explicit. |
| 303 | See Other | Get the result from another URL with GET. | Redirect after a form POST so a refresh doesn’t resubmit it. |
| 304 | Not Modified | The cached copy is still valid. | Answering a conditional request with If-None-Match or If-Modified-Since. |
| 307 | Temporary Redirect | Repeat the same request at another URL. | Temporary redirect that must keep the method and body. |
| 308 | Permanent Redirect | Repeat the same request at a new permanent URL. | Like 301, but the method and body must not change. |
Client error (4xx)
| Code | Name | Meaning | When to use |
|---|---|---|---|
| 400 | Bad Request | The request is malformed or invalid. | Unparseable JSON, missing required fields, wrong types. |
| 401 | Unauthorized | Authentication is missing or invalid. | No token, or an expired one. Despite the name, it means “unauthenticated”. |
| 402 | Payment Required | Reserved; used by some APIs for billing problems. | Plan limit reached or payment failed. |
| 403 | Forbidden | The client is known but not allowed to do this. | Logged in, but lacking permission. |
| 404 | Not Found | Nothing exists at this URL. | Unknown routes or IDs. Also used to hide resources the client may not know about. |
| 405 | Method Not Allowed | This URL doesn’t support that HTTP method. | A POST to a read-only endpoint. Include an Allow header. |
| 406 | Not Acceptable | No representation matches the Accept header. | The client asked for XML from a JSON-only API. |
| 408 | Request Timeout | The client took too long to send the request. | Idle connections. Clients can safely retry. |
| 409 | Conflict | The request conflicts with the current state. | Duplicate unique values, or an edit based on a stale version. |
| 410 | Gone | The resource existed but was removed for good. | Deleted content or retired API versions. Stronger than 404. |
| 411 | Length Required | A Content-Length header is required. | Uploads without a declared size. |
| 412 | Precondition Failed | A conditional header didn’t match. | If-Match with an outdated ETag, to prevent lost updates. |
| 413 | Content Too Large | The request body is bigger than the server accepts. | Uploads over the size limit. |
| 414 | URI Too Long | The URL is longer than the server will handle. | Huge query strings. Move the data into a POST body. |
| 415 | Unsupported Media Type | The body’s format isn’t supported. | Sending form data to a JSON endpoint, or a wrong Content-Type. |
| 416 | Range Not Satisfiable | The requested byte range is outside the file. | A Range request past the end of the resource. |
| 418 | I’m a teapot | An April Fools’ joke from 1998 that stuck around. | Easter eggs only. |
| 422 | Unprocessable Content | The request is well-formed but fails validation. | Valid JSON with invalid values, like an end date before the start date. |
| 423 | Locked | The resource is locked. | WebDAV, or a record being edited by someone else. |
| 425 | Too Early | The server won’t risk processing a request that might be replayed. | TLS early data (0-RTT). |
| 426 | Upgrade Required | The client must switch to another protocol. | Forcing a newer TLS or HTTP version. |
| 428 | Precondition Required | The request must be conditional. | Requiring If-Match on updates to avoid lost writes. |
| 429 | Too Many Requests | The client is sending requests too fast. | Rate limiting. Include a Retry-After header. |
| 431 | Request Header Fields Too Large | Headers are too big. | Oversized cookies are the usual culprit. |
| 451 | Unavailable For Legal Reasons | Blocked for legal reasons. | Content removed by court order or blocked in a country. |
Server error (5xx)
| Code | Name | Meaning | When to use |
|---|---|---|---|
| 500 | Internal Server Error | Something went wrong on the server. | Unhandled exceptions. Log the details, don’t leak them to the client. |
| 501 | Not Implemented | The server doesn’t support this functionality. | An HTTP method the server doesn’t recognise at all. |
| 502 | Bad Gateway | A proxy got an invalid response from the server behind it. | The app behind nginx or a load balancer crashed or returned garbage. |
| 503 | Service Unavailable | The server can’t handle requests right now. | Maintenance or overload. Include Retry-After if you know when it’s back. |
| 504 | Gateway Timeout | A proxy didn’t get a response in time. | The upstream app is too slow or hanging. |
| 505 | HTTP Version Not Supported | The HTTP version isn’t supported. | Rare; very old or very new protocol versions. |
| 507 | Insufficient Storage | The server has no room to store the result. | Disk full, or a storage quota reached. |
| 508 | Loop Detected | The server found an infinite loop while processing. | WebDAV, or a redirect or proxy cycle. |
| 511 | Network Authentication Required | The client must log in to get network access. | Captive portals on hotel and airport Wi-Fi. |
Something not working, or a result looks wrong? Report a problem with this tool