navaja.dev / http-status

HTTP status codes

Every HTTP status code, what it means and what to do about it. Type a number or a word like timeout, redirect or cookie.

1xx Informational The request was received and is still being processed.

100 Continue

The server got the request headers and the client should send the body. Clients send Expect: 100-continue before a large upload to check it will be accepted first. curl does this over HTTP/1.1 for bodies over 1 MB.

101 Switching Protocols

The server agrees to change protocol, as asked in the Upgrade header. You see it when a WebSocket connection opens.

102 Processing

WebDAV: the server is still working on a long request. Deprecated; rarely seen today.

103 Early Hints

Sent before the final response with Link headers, so the browser can start preloading CSS, fonts or scripts while the server is still building the page.

2xx Success The request worked.

200 OK

The request worked. For GET the body is the resource; for POST it is the result of the action.

201 Created

A new resource was created, usually by POST or PUT. The Location header should point to it.

202 Accepted

The request was accepted for processing but isn't done yet, like a queued job. The body often says where to check its status.

203 Non-Authoritative Information

The response was changed by a proxy in between, so it isn't exactly what the origin sent. Rare.

204 No Content

It worked and there is no body. Common for DELETE, for PUT that saves without returning anything, and for CORS preflights.

205 Reset Content

It worked; the client should reset the form or view that sent the request. Rare.

206 Partial Content

The body is only the part asked for with a Range header. Used for resuming downloads and seeking in video.

207 Multi-Status

WebDAV: the body is XML with a separate status for each of several resources.

208 Already Reported

WebDAV: members of a collection already listed earlier in the same 207 response.

226 IM Used

The response is a delta (changes) applied to the current resource, for delta encoding. Rare.

3xx Redirection The client has to go somewhere else to finish.

300 Multiple Choices

There is more than one version of the resource (for example different formats) and the client should pick one. Rare in practice.

301 Moved Permanently

The resource has a new permanent URL, given in Location. Browsers and search engines update to it and pass ranking to the new URL. Clients may turn a POST into a GET when following it; use 308 to keep the method.

302 Found

A temporary redirect to the URL in Location. Keep using the old URL later. Clients usually turn POST into GET; use 307 to keep the method.

303 See Other

Go GET the URL in Location. Used after a form POST so that refreshing the result page doesn't submit the form again (Post/Redirect/Get).

304 Not Modified

The cached copy is still good: the client sent If-None-Match or If-Modified-Since and nothing changed. There is no body; use the cached one.

305 Use Proxy

Deprecated and ignored by browsers for security reasons.

306 (Unused)

Was Switch Proxy in an early HTTP/1.1 draft. Reserved and no longer used.

307 Temporary Redirect

Like 302, but the client must repeat the same method and body at the new URL. Browsers also show 307 for an internal HSTS upgrade from http to https.

308 Permanent Redirect

Like 301, but the method and body must stay the same. The right choice for permanently moving an API endpoint that takes POST.

4xx Client errors Something is wrong with the request, so fix it before retrying.

400 Bad Request

The server can't or won't handle the request because something in it is wrong: invalid JSON, a missing field, a malformed header or a cookie that is too large. The body usually says which.

401 Unauthorized

You need to log in: no credentials were sent, or they are wrong or expired. The response must include a WWW-Authenticate header. Despite the name it means unauthenticated; compare 403.

402 Payment Required

Reserved for future use. Some APIs use it when a plan's quota or payment has run out.

403 Forbidden

The server knows who you are (or doesn't care) and still refuses. Logging in again won't help. Also returned for blocked IPs, missing file permissions on the server, and WAF blocks.

404 Not Found

Nothing exists at this URL, or the server won't say that something does. Check the path, the spelling and the trailing slash.

405 Method Not Allowed

The URL exists but doesn't accept this method, like POST to a read-only page. The Allow header lists the methods that work.

406 Not Acceptable

The server can't produce a response in any format the Accept headers ask for.

407 Proxy Authentication Required

Like 401, but for a proxy between you and the server. Send Proxy-Authorization.

408 Request Timeout

The client took too long to send the request, and the server closed the connection. Usually safe to retry.

409 Conflict

The request conflicts with the current state: an edit on an outdated version, or creating something that already exists. Fetch the latest state and try again.

410 Gone

The resource was deliberately removed and won't come back. Search engines drop it faster than a 404.

411 Length Required

The server needs a Content-Length header for this request.

412 Precondition Failed

A condition in If-Match or If-Unmodified-Since wasn't met, so nothing was changed. Used to stop lost updates.

413 Content Too Large

The request body is over the server's limit. In nginx the limit is client_max_body_size (1 MB by default). Formerly Payload Too Large, and before that Request Entity Too Large.

414 URI Too Long

The URL is longer than the server accepts, often from a huge query string. Send the data in a POST body instead. Formerly Request-URI Too Long.

415 Unsupported Media Type

The server doesn't accept the body's format. Check the Content-Type header, for example application/json for JSON.

416 Range Not Satisfiable

The Range asked for is outside the file, for example resuming a download that is already complete. Formerly Requested Range Not Satisfiable.

417 Expectation Failed

The server can't meet the Expect header. Retry without Expect: 100-continue.

418 I'm a teapot

An April Fools' joke from 1998 (RFC 2324). Reserved so it is never given a real meaning; some sites use it to turn away bots.

419 Page Expired Laravel

Laravel: the CSRF token is missing or expired, usually because a form sat open too long. Reload the page and submit again.

421 Misdirected Request

The request reached a server that can't answer for this host, usually because an HTTP/2 connection was reused for another domain on the same certificate.

422 Unprocessable Content

The body is well formed but its contents are invalid, like a failed validation. Many APIs (Rails, Laravel, FastAPI) use it for form errors. Formerly Unprocessable Entity.

423 Locked

WebDAV: the resource is locked.

424 Failed Dependency

WebDAV: the request failed because an earlier one it depended on failed.

425 Too Early

The server won't risk processing a request sent in TLS 1.3 early data, because it could be replayed. Retry after the handshake.

426 Upgrade Required

The client must switch to another protocol, given in the Upgrade header.

428 Precondition Required

The server requires a conditional request (If-Match), to stop clients overwriting each other's changes.

429 Too Many Requests

Rate limited: you sent too many requests in a given time. Wait for the number of seconds in Retry-After if it is there, and back off exponentially.

431 Request Header Fields Too Large

The headers are too big, most often because of too many or too large cookies. Clearing the site's cookies usually fixes it.

444 No Response nginx

nginx closed the connection without sending anything. Used in nginx configs to drop unwanted requests; clients see an empty reply.

451 Unavailable For Legal Reasons

Blocked for legal reasons, such as a court order or government censorship. The number is a nod to Fahrenheit 451.

494 Request Header Too Large nginx

nginx: the request headers were too large (often cookies). Shown to clients as 400.

495 SSL Certificate Error nginx

nginx: the client certificate is invalid. Shown to clients as 400.

496 SSL Certificate Required nginx

nginx: a client certificate is required but none was sent. Shown to clients as 400.

497 HTTP Request Sent to HTTPS Port nginx

nginx: a plain http request reached a port that expects https. Shown to clients as 400 unless redirected with error_page 497.

499 Client Closed Request nginx

nginx: the client hung up before the server answered, often because it timed out first. You see it in logs, never in a browser. Look for slow upstreams.

5xx Server errors The server failed on a request that looked valid.

500 Internal Server Error

Something broke on the server and it has no more specific code. It's a bug or crash on their side: check the server logs.

501 Not Implemented

The server doesn't support the method or feature at all, for any resource.

502 Bad Gateway

A proxy or load balancer (nginx, a CDN) got an invalid response from the app behind it, or couldn't connect. Usually the app crashed, isn't running, or closed the connection.

503 Service Unavailable

The server is overloaded or down for maintenance. Temporary; Retry-After may say when to try again.

504 Gateway Timeout

A proxy or load balancer waited too long for the app behind it. The request may still finish on the server, so be careful retrying a POST.

505 HTTP Version Not Supported

The server doesn't support the HTTP version of the request.

506 Variant Also Negotiates

A server configuration error in content negotiation. Rare.

507 Insufficient Storage

WebDAV: the server has no room to store what was sent.

508 Loop Detected

WebDAV: the server found an infinite loop while processing the request.

509 Bandwidth Limit Exceeded cPanel

cPanel and Apache hosting: the site used up its monthly bandwidth allowance. The site owner has to raise the limit or wait for the reset.

510 Not Extended

Obsolete: further extensions to the request are needed.

511 Network Authentication Required

You have to log in to the network first, like a hotel or airport Wi-Fi captive portal.

520 Web Server Returned an Unknown Error Cloudflare

Cloudflare: the origin sent an empty, unknown or unexpected response, or reset the connection.

521 Web Server Is Down Cloudflare

Cloudflare: the origin refused the connection. The server is down, or a firewall blocks Cloudflare's IPs.

522 Connection Timed Out Cloudflare

Cloudflare: the TCP connection to the origin timed out. Check the server is up and that Cloudflare's IPs aren't blocked.

523 Origin Is Unreachable Cloudflare

Cloudflare: it can't reach the origin at all, often a wrong DNS record.

524 A Timeout Occurred Cloudflare

Cloudflare: it connected to the origin but got no HTTP response within 100 seconds (on most plans). Move long work to a background job.

525 SSL Handshake Failed Cloudflare

Cloudflare: the TLS handshake with the origin failed.

526 Invalid SSL Certificate Cloudflare

Cloudflare: in Full (strict) mode, the origin's certificate is invalid or expired.

529 Site Is Overloaded unofficial

Some large APIs return it when they are overloaded. Retry later with backoff.

530 Origin Error Cloudflare

Cloudflare: shown together with a 1xxx error (like 1016, origin DNS error). Look up the 1xxx code for the cause.

Which status code should I use?

SituationCode
Not logged in, or the token expired401 Unauthorized
Logged in, but not allowed to do this403 Forbidden (or 404 to hide that it exists)
Malformed request (bad JSON, wrong type)400 Bad Request
Valid JSON that fails validation422 Unprocessable Content (or 400)
Duplicate, or edited an outdated version409 Conflict
Rate limit reached429 Too Many Requests with Retry-After
Created something201 Created with Location
Success with nothing to return204 No Content
Page moved for good301 (or 308 to keep POST)
Temporary redirect302 (or 307 to keep POST)
After a form POST303 See Other
Down for maintenance503 Service Unavailable with Retry-After

401 vs 403

401 means the server doesn't know who you are: log in or send a valid token, then try again. 403 means it knows (or doesn't need to) and the answer is still no, so new credentials won't help unless they belong to someone with more access.

502 vs 503 vs 504

All three usually come from a proxy, load balancer or CDN in front of the app. 502 Bad Gateway: the app answered with garbage or the connection failed, often because it crashed or isn't listening. 503 Service Unavailable: the server says it's overloaded or in maintenance. 504 Gateway Timeout: the app didn't answer in time. Look at the app's logs and the proxy's timeout settings.

Which codes are safe to retry?

408, 429, 502, 503 and 504 are usually temporary: retry with exponential backoff, and honor Retry-After. Don't retry other 4xx codes without changing the request. Be careful retrying a POST after a timeout, since the first attempt may have worked; use an idempotency key if the API supports one.

Questions

What does HTTP 404 mean?

Not Found: the server has nothing at that URL. Check the path, spelling and trailing slash. If it was removed for good, 410 Gone tells search engines to drop it sooner.

What is the difference between 301 and 302?

301 is permanent: browsers cache it and search engines move rankings to the new URL. 302 is temporary: keep using the old URL. 308 and 307 are the same pair, but they keep the method and body, so a POST stays a POST.

What does 429 Too Many Requests mean?

You hit a rate limit. Wait the number of seconds in the Retry-After header if there is one, and slow down or back off exponentially.

What is a 499 error?

It's an nginx log code: the client closed the connection before the server answered, usually because the client's own timeout was shorter than the request took.

What do Cloudflare 520, 521, 522 and 524 mean?

They come from Cloudflare, not your app. 520: the origin sent an unexpected or empty response. 521: the origin refused the connection. 522: connecting to the origin timed out. 524: the origin connected but took over 100 seconds to answer.

What does 304 Not Modified mean?

The browser's cached copy is still current, so the server sent no body. It's normal and saves bandwidth; it shows up when you reload a page.

Is 418 I'm a teapot a real status code?

It started as an April Fools' joke (RFC 2324) and is reserved, so it will never mean anything else. Some sites use it to refuse bots.