Skip to content
HTTP Status Codes

HTTP status codes — every code, what it means, and the RFC it comes from

A complete list of HTTP status codes with the specification each one actually comes from. Most references still cite RFC 2616, retired in 2014; the core codes here are cited to RFC 9110, published June 2022, with WebDAV, RFC 6585 and RFC 7725 named where they apply. Non-standard codes from Cloudflare, nginx and IIS are listed separately and clearly labelled, never mixed in. Search the table, look up a code, and read the comparisons that decide which one you should be returning. Nothing is uploaded or saved.

  • Nothing is uploaded or saved
  • Works offline
Find a code

Three digits, straight from your log line or your network tab.

Code
404
Class
4xx
Defined by
RFC 9110 §15.5.5
In practice
common

Not Found

The server has no current representation for this URI and will not say whether it ever did or ever will.

Every registered status code
63 of 63 shown

1xx — Informational

The request was received and the process is continuing. A 1xx is an interim response: it is never the final answer, it carries no body, and older HTTP/1.0 clients are entitled to ignore it entirely. If you are debugging and see one, something else is still coming.

CodeNameMeaningDefined by
100ContinuerareThe server has read the request headers, has not rejected the request, and the client should now send the body. It only ever appears in reply to a request carrying “Expect: 100-continue”.The point is to avoid uploading a large body to a server that was going to answer 401 or 413 anyway.RFC 9110§15.2.1
101Switching ProtocolsThe server agrees to change protocol on this connection, as asked for in the Upgrade header. This is how a WebSocket handshake completes.RFC 9110§15.2.2
102ProcessinghistoricalA WebDAV interim response meaning the server has accepted the request but has not finished, sent so the client does not time out.Removed from WebDAV when RFC 4918 replaced RFC 2518, but never deregistered. Treat it as obsolete.RFC 2518
103Early HintsrareSent before the real response so the browser can start fetching resources named in Link headers while the server is still assembling the page.Genuinely useful for preload and preconnect hints, and supported by the major browsers and CDNs — but still rarely deployed by ordinary applications.RFC 8297

2xx — Successful

The request was received, understood and accepted. Which 2xx you pick matters more than it looks: 201 tells a client something now exists at a new URI, 204 tells a browser not to navigate away, and 206 is the whole basis of video seeking and resumable downloads.

CodeNameMeaningDefined by
200OKThe request succeeded, and the body is the result of it.RFC 9110§15.3.1
201CreatedThe request succeeded and created one or more new resources. The Location header should give the URI of the primary one.RFC 9110§15.3.2
202AcceptedrareThe request was accepted for processing, but nothing has happened yet and it may still fail. There is deliberately no promise about the outcome.RFC 9110§15.3.3
203Non-Authoritative InformationrareThe response is a 200 that some proxy in the middle has modified. Rare, and easy to confuse with 200.RFC 9110§15.3.4
204No ContentSuccess, and there is deliberately no body. Headers may still carry useful information. A browser will not navigate away on a 204.RFC 9110§15.3.5
205Reset ContentrareSuccess, no body, and the client should clear the form that produced the request so the user can enter another.RFC 9110§15.3.6
206Partial ContentThe server is returning only the byte ranges the client asked for in the Range header. Video seeking and resumable downloads run on this.RFC 9110§15.3.7
207Multi-StatusrareA WebDAV response whose XML body carries a separate status for each of several resources the one request touched.RFC 4918§11.1
208Already ReportedrareInside a WebDAV 207 body, marks a collection whose members were already listed under an earlier binding, so they are not repeated.RFC 5842§7.1
226IM UsedhistoricalThe response is the result of applying one or more instance manipulations — delta encoding — to the current resource.RFC 3229§10.4.1

3xx — Redirection

Further action is needed to complete the request, usually at the URI in the Location header. The five that matter differ on two questions only — is this permanent, and does the method survive — and getting that pair wrong is the single most common redirect bug.

CodeNameMeaningDefined by
300Multiple ChoiceshistoricalThe request has more than one possible response and the server is not choosing. There is no standard way to present the alternatives, which is why nothing uses it.RFC 9110§15.4.1
301Moved PermanentlyThe resource has a new permanent URI, given in Location. Caches and search engines are expected to update their records.For historical reasons a user agent is allowed to change POST to GET when following it. If the method must survive, use 308.RFC 9110§15.4.2
302FoundThe resource is temporarily somewhere else. The original URI stays the one to use next time.Same historical POST-to-GET rewriting as 301. Use 307 if the method must survive, or 303 if you want the rewrite on purpose.RFC 9110§15.4.3
303See OtherThe result of this request is at another URI, and the client should fetch it with GET regardless of the method it just used.The correct answer to a successful POST when you want a refresh to reload the result page rather than re-submit the form.RFC 9110§15.4.4
304Not ModifiedThe client’s cached copy is still current, so no body is sent. Answers a conditional request carrying If-None-Match or If-Modified-Since.RFC 9110§15.4.5
305Use ProxyhistoricalDeprecated. It once told the client to reach the resource through a named proxy.Deprecated for security reasons; RFC 9110 says a client must not act on it.RFC 9110§15.4.6
306(Unused)historicalReserved. It was used in an early draft and is no longer assigned to anything.RFC 9110§15.4.7
307Temporary RedirectLike 302, but the method and the body must be kept exactly as they were when following it.RFC 9110§15.4.8
308Permanent RedirectLike 301, but the method and the body must be kept. This is the redirect to use for a permanently moved API endpoint.Originally defined in RFC 7538 and folded into RFC 9110.RFC 9110§15.4.9

4xx — Client error

The request was faulty, or the client is not allowed to make it. “Client” means the caller, not necessarily a person doing something wrong: 404 and 429 are perfectly ordinary answers a healthy server gives all day. The rule is that repeating the identical request will not help until the client changes something.

CodeNameMeaningDefined by
400Bad RequestThe server will not process the request because something about it is malformed — bad syntax, a framing error, deceptive routing.Not a general-purpose “something went wrong”. If the request was well formed and the problem is its content, 422 is the honest answer.RFC 9110§15.5.1
401UnauthorizedThe request lacks valid authentication for the target. The response must carry a WWW-Authenticate header naming a scheme the client can try.Misnamed: it means unauthenticated. “You are known and still not allowed” is 403.RFC 9110§15.5.2
402Payment RequiredrareReserved for future use. There is no standard payment flow behind it.Some APIs use it for a quota or billing failure. That is a local convention, not a specification.RFC 9110§15.5.3
403ForbiddenThe server understood the request and refuses to authorise it. Sending different credentials will not help.A server may answer 404 instead when it does not want to admit the resource exists. That is explicitly allowed.RFC 9110§15.5.4
404Not FoundThe server has no current representation for this URI and will not say whether it ever did or ever will.RFC 9110§15.5.5
405Method Not AllowedThe URI exists, but this method is not supported on it. The response must carry an Allow header listing the methods that are.RFC 9110§15.5.6
406Not AcceptablerareNothing the server can produce matches the Accept headers the client sent.Most servers ignore the mismatch and send their default representation instead, which the spec permits.RFC 9110§15.5.7
407Proxy Authentication Requiredrare401, but for the proxy rather than the origin server. Comes with Proxy-Authenticate instead of WWW-Authenticate.RFC 9110§15.5.8
408Request TimeoutrareThe server closed an idle connection because the client did not produce a request in time.Often seen on a keep-alive connection the server reaped; the browser usually retries transparently.RFC 9110§15.5.9
409ConflictThe request clashes with the current state of the resource — an edit against a version that has moved on, a duplicate unique key.RFC 9110§15.5.10
410GoneThe resource was here, it is permanently gone, and no forwarding address exists. Stronger and more deliberate than 404.RFC 9110§15.5.11
411Length RequiredrareThe server refuses the request because it has no Content-Length header.RFC 9110§15.5.12
412Precondition FailedrareA condition the client attached — If-Match, If-Unmodified-Since — was false when the server evaluated it.This is how optimistic locking is reported: your ETag no longer matches, so your update was not applied.RFC 9110§15.5.13
413Content Too LargeThe request body is larger than the server is willing or able to process.Renamed by RFC 9110; older documents call it “Payload Too Large” and RFC 2616 called it “Request Entity Too Large”.RFC 9110§15.5.14
414URI Too LongrareThe request target is longer than the server is willing to interpret.Almost always a GET that should have been a POST, or a redirect loop appending a query parameter each time.RFC 9110§15.5.15
415Unsupported Media TypeThe body is in a format this resource does not accept.The usual cause is a missing or wrong Content-Type on a JSON request.RFC 9110§15.5.16
416Range Not SatisfiablerareNone of the ranges asked for overlap the current size of the resource.RFC 9110§15.5.17
417Expectation FailedrareThe expectation in the Expect header cannot be met by this server.RFC 9110§15.5.18
418(Unused) — “I’m a Teapot”historicalNot a usable status. 418 comes from RFC 2324, the Hyper Text Coffee Pot Control Protocol, published on 1 April 1998 as a joke. IANA keeps 418 reserved so nobody can assign it to anything real.RFC 9110 §15.5.19 lists 418 as (Unused) for exactly this reason. Do not return it from a real service: proxies and clients have no defined behaviour for it.RFC 2324§2.3.2
421Misdirected RequestrareThe request reached a server that is not configured to answer for this authority — a connection reused for a host it does not serve.Introduced by HTTP/2 (RFC 7540), where one connection can be reused across origins, and moved into RFC 9110.RFC 9110§15.5.20
422Unprocessable ContentThe syntax is fine and the content type is understood, but the content itself cannot be processed — validation failed.Started life in WebDAV (RFC 4918) as “Unprocessable Entity” and was adopted into core HTTP by RFC 9110 under the new name.RFC 9110§15.5.21
423LockedrareThe WebDAV resource, or its parent, is locked.RFC 4918§11.3
424Failed DependencyrareThe request failed because an earlier request it depended on failed, so this one was never attempted.RFC 4918§11.4
425Too EarlyrareThe server will not risk processing a request replayed from TLS 1.3 early data, because a replay could be an attack.RFC 8470§5.2
426Upgrade RequiredrareThe server refuses this request on the current protocol and names the required one in an Upgrade header.RFC 9110§15.5.22
428Precondition RequiredrareThe server requires the request to be conditional, so that a lost-update race cannot happen silently.RFC 6585§3
429Too Many RequestsThe client has sent too many requests in a given period. A Retry-After header should say when to try again.RFC 6585§4
431Request Header Fields Too LargerareThe headers are too big — either in total or one field on its own. An oversized cookie is the usual cause.RFC 6585§5
451Unavailable For Legal ReasonsrareAccess is denied because of a legal demand — a court order, a takedown, a state block. The body should identify who made the demand.The number is a deliberate reference to Fahrenheit 451. It is a real, registered status all the same.RFC 7725

5xx — Server error

The server knows it failed, or cannot do what was asked, and the request itself was fine. That distinction is the whole point of the class: a 5xx is an admission of fault, so returning one for bad user input sends your monitoring after a problem that does not exist.

CodeNameMeaningDefined by
500Internal Server ErrorThe server hit a condition it could not handle and has nothing more specific to say. The generic catch-all.RFC 9110§15.6.1
501Not ImplementedrareThe server does not support the functionality needed — for a method it does not recognise at all, rather than one it will not allow here.The difference from 405 is scope: 405 means “not on this resource”, 501 means “not by this server, on anything”.RFC 9110§15.6.2
502Bad GatewayA server acting as a gateway got an invalid response from the server upstream of it.Nearly always your reverse proxy telling you the application behind it crashed, or was never listening on the port the proxy expects.RFC 9110§15.6.3
503Service UnavailableThe server cannot handle the request right now — overloaded, or deliberately down for maintenance. Retry-After can say for how long.The right status for planned maintenance: it tells search engines to come back rather than to drop the page.RFC 9110§15.6.4
504Gateway TimeoutA gateway waited for the upstream server and gave up. The difference from 502 is that upstream answered nothing, rather than answering badly.RFC 9110§15.6.5
505HTTP Version Not SupportedrareThe server refuses the major HTTP version used in the request.RFC 9110§15.6.6
506Variant Also NegotiateshistoricalA transparent content-negotiation misconfiguration: the chosen variant is itself set up to negotiate, so the process cannot terminate.RFC 2295§8.1
507Insufficient StoragerareThe WebDAV server cannot store what is needed to complete the request.RFC 4918§11.5
508Loop DetectedrareThe server stopped an operation because it found an infinite loop while processing a WebDAV request with Depth: infinity.RFC 5842§7.2
510Not Extended (obsoleted)historicalMeant to say that further extensions to the request were required. Its specification, the HTTP Extension Framework, has been moved to historic status.IANA marks this entry obsoleted. It should not be used in new work.RFC 2774
511Network Authentication RequiredrareThe client must authenticate to get onto the network. Intended for captive portals, so that an intercepted response is not mistaken for the real site.RFC 6585§6
301 vs 302 vs 303 vs 307 vs 308

Two questions separate all five, and most redirect bugs are one of them answered wrongly. Is the move permanent, and does the request method survive it? A 301 is allowed to turn your POST into a GET — which is exactly why a permanently moved API endpoint wants 308.

CodeNameLifetimeMethodReach for it when
301Moved PermanentlyPermanentMay change POST to GETA page or a whole site that has moved for good. The one search engines act on.
302FoundTemporaryMay change POST to GETA short-lived detour where the original URI stays canonical. Ambiguous on method — prefer 303 or 307 when a POST is involved.
303See OtherTemporaryAlways becomes GETAfter a successful POST, to send the browser to a result page a refresh can safely reload.
307Temporary RedirectTemporaryPreserved, body and allA temporary move where a POST must arrive at the new URI still a POST.
308Permanent RedirectPermanentPreserved, body and allA permanently moved API endpoint. 301 would risk turning your POST into a GET.
Non-standard codes — not in the IANA registry

None of these are HTTP status codes in the standards sense. Each is emitted by one particular piece of software and means whatever that software says it means. They are here because you will meet them in logs and need to look them up — never because your own service should return one. Nothing outside the originating software knows what they are.

Cloudflare

A 5xx in this range comes from Cloudflare’s edge, not from your server — your server usually never saw the request. The number tells you which leg of the connection failed.

520Web Server Returned an Unknown ErrorThe origin returned something empty, unexpected or malformed that Cloudflare could not turn into a valid HTTP response. The catch-all of this range.
521Web Server Is DownThe origin refused the connection outright — nothing is listening, or a firewall is blocking Cloudflare’s IP ranges.
522Connection Timed OutThe TCP handshake to the origin did not complete in time. Usually a firewall dropping packets silently rather than rejecting them.
523Origin Is UnreachableCloudflare could not route to the origin at all — commonly a DNS record pointing at an address that no longer exists.
524A Timeout OccurredThe connection succeeded but the origin did not finish its response inside Cloudflare’s time limit. A slow query, not a down server.
525SSL Handshake FailedThe TLS handshake between Cloudflare and the origin failed — mismatched cipher suites, or no valid certificate on the origin.
526Invalid SSL CertificateThe origin presented a certificate Cloudflare could not validate, while the zone is set to a strict SSL mode that requires a valid one.
527Railgun ErrorA failure between Cloudflare and a Railgun listener. Railgun has been retired, so this is now historical.
530Site Frozen / paired errorAlways accompanied by a Cloudflare 1xxx error code shown in the body; the 1xxx number is the one that tells you what actually happened.

nginx

These never travel over the wire as a status line — nginx writes them to its own access log to record how a connection ended. Searching for one in a log is the only way you will meet them.

444No Responsenginx closed the connection without sending anything at all. It is what the “return 444;” directive does, usually to drop unwanted traffic cheaply.
494Request header too largeThe request headers exceeded large_client_header_buffers. Logged internally; the client sees 400.
495SSL Certificate ErrorClient certificate verification failed during a mutual-TLS handshake.
496SSL Certificate RequiredThe client presented no certificate where the configuration required one.
497HTTP Request Sent to HTTPS PortA plain HTTP request arrived on a port configured for TLS.
499Client Closed RequestThe client disconnected before nginx could answer. A burst of these usually means your upstream is slow enough that users are giving up, not that anything is broken in nginx.

IIS sub-status codes

IIS appends a decimal sub-code to a normal status — 401.3, 404.13 — in its logs and on its own error pages. The client still receives the plain status; the fraction is for you, and it is the part that names the actual cause.

401.1Logon failedThe credentials supplied were rejected at logon.
401.2Logon failed due to server configurationThe authentication method the client used is not enabled on the server.
401.3Unauthorized due to ACL on resourceWindows file-system permissions denied access to the file itself.
403.4SSL requiredThe resource is configured to require HTTPS and the request arrived over HTTP.
403.14Directory listing deniedNo default document exists and directory browsing is switched off.
404.4No handler configuredNo handler mapping matches the requested extension.
404.13Content length too largeThe request body exceeded maxAllowedContentLength — the IIS-level limit, which is separate from your application’s.
500.19Configuration data is invalidweb.config could not be read or contains a section the server will not accept.
500.30ASP.NET Core app failed to startThe ASP.NET Core Module started the process and it exited before it began listening.

Other servers

One more that turns up often enough in shared-hosting logs to be worth naming. Codes such as 420 and 598 are frequently listed elsewhere as non-standard statuses; they are left out here because their definitions could not be pinned to a source that still publishes them.

509Bandwidth Limit ExceededEmitted by an Apache bandwidth-limiting module and by cPanel when an account passes its monthly transfer allowance. Never registered with IANA.

How it works

  1. 1

    Find the code you are holding

    Type a number into the lookup and you get that code alone: its reason phrase, what it means in a sentence, the RFC and section that define it, and whether it is something you will meet in practice or a historical curiosity. Three digits is usually all you have when a log line hands you one.

  2. 2

    Or search by what you are trying to say

    The filter runs over the name, the meaning and the notes, not just the number. Searching “redirect”, “cache”, “rate limit” or “authentication” narrows the table to the codes that concern it, which is the more common direction — you know the situation and you want the right code for it.

  3. 3

    Read the class before the code

    Each of the five classes carries a real explanation, because the class is doing most of the work. A 4xx says the caller must change something before retrying; a 5xx is the server admitting fault. Returning 500 for bad user input is not a cosmetic mistake — it sends your on-call after a problem that does not exist.

  4. 4

    Settle the four redirects with the table, not from memory

    Two questions separate 301, 302, 303, 307 and 308: is the move permanent, and does the method survive it. The matrix answers both for all five at once. A 301 is allowed to turn your POST into a GET, which is why a permanently moved API endpoint wants 308 instead.

  5. 5

    Check the non-standard section separately

    Cloudflare’s 520–527, nginx’s 444 and 499, and the IIS sub-codes such as 404.13 are in their own section with the software that emits each one named. They are worth looking up and must never be returned by your own service — nothing outside their originating software knows what they mean.

Frequently asked questions

Which RFC should I be citing in 2026?

RFC 9110, HTTP Semantics, published June 2022. It replaced RFC 7230 through 7235, which had themselves replaced RFC 2616 back in 2014, and it is where the status code registry now points for the core codes. It also absorbed three codes that used to live elsewhere: 308 came from RFC 7538, 421 from RFC 7540 (HTTP/2), and 422 from WebDAV’s RFC 4918, renamed from “Unprocessable Entity” to “Unprocessable Content”. Not everything moved, though, which is why this table cites per code rather than putting one RFC in a footer: 429 is RFC 6585, 451 is RFC 7725, and 423, 424 and 507 are still RFC 4918.

Is 418 I’m a Teapot real?

It is a real registration and not a real status. It comes from RFC 2324, the Hyper Text Coffee Pot Control Protocol, published on 1 April 1998 as a joke. RFC 9110 lists 418 as “(Unused)” and IANA keeps it reserved specifically so it can never be assigned to something serious. So you can look it up and you should not return it: no proxy, cache or client library has any defined behaviour for it, and “our API answers 418” is a support ticket waiting to be filed.

What is the difference between 301, 302, 307 and 308?

Two independent questions. Permanence: 301 and 308 say the resource has moved for good and caches and search engines should update; 302, 303 and 307 say it is temporary and the original URI stays canonical. Method: 307 and 308 require the method and body to be preserved exactly, 303 always turns the follow-up into a GET, and 301 and 302 sit in the middle — for historical reasons a user agent is permitted to rewrite POST to GET, and in practice they do. So a permanently moved API endpoint wants 308, not 301; a temporarily moved one wants 307; and the redirect after a successful form POST wants 303, so that pressing refresh reloads the result page instead of re-submitting the form.

When should I use 401 and when 403?

401 means unauthenticated, despite being named “Unauthorized”. It says the request carried no valid credentials and the response must include a WWW-Authenticate header naming a scheme the client can try — sending different credentials might work. 403 means authenticated and still refused: the server understood who you are and will not do it, so retrying with other credentials will not help. The everyday test is whether logging in as someone else could change the answer. There is also a legitimate third option: a server is explicitly allowed to answer 404 instead of 403 when admitting the resource exists would itself leak something.

Should a deleted page return 404 or 410?

410 when you are certain it is gone for good and there is no forwarding address; 404 when you are not, or when you simply do not know. 410 is the stronger statement — “this was here, it has been removed, stop asking” — and crawlers treat it as more decisive than a 404, which they will re-check for a while in case it was a mistake. The practical difference is small enough that it is not worth agonising over: both remove a page from a search index eventually, and neither is a substitute for a 301 to the page that replaced it.

What should a 429 actually include?

A Retry-After header, and a body that explains the limit. Retry-After takes either a number of seconds or an HTTP-date, and without it the client is left guessing — which in practice means retrying immediately and making your overload worse. RFC 6585 defines the code and recommends the body describe the limit; the widely used RateLimit header fields for the remaining quota are a separate, later specification and are not part of it. Note also that 429 is about the client’s rate, while 503 is about your capacity: use 503 with Retry-After when everyone is affected.

Why do I get a 502 or 504 when my server looks fine?

Because neither comes from your application — both come from something in front of it. 502 Bad Gateway means the reverse proxy reached your service and got back something it could not parse as an HTTP response, which usually means the process crashed mid-request or nothing is listening on the port the proxy is configured for. 504 Gateway Timeout means the proxy connected fine and gave up waiting, so your code is running and simply slow. That distinction is the fastest triage available: 502 points at the process, 504 points at a query.

What are Cloudflare’s 5xx codes and why are they separate here?

Because they are not HTTP status codes in the standards sense at all — they are Cloudflare’s own numbers in the 520–527 range, returned by its edge to tell you which leg of the connection to your origin failed. 521 means your server refused the connection, 522 means the TCP handshake timed out (usually a firewall dropping Cloudflare’s IP ranges silently), 524 means the connection worked and your server did not finish in time, and 525 and 526 are TLS problems between the edge and the origin. Mixing them into the IANA table would make this page lie about the one thing it is for. The same applies to nginx’s 444 and 499, which never travel over the wire at all — nginx writes them into its own access log to record how a connection ended.

Does anything I type into the lookup leave my browser?

No. The whole registry is part of the JavaScript this page already loaded, so both the search and the lookup are running over an array in memory. There is no API call behind them, nothing is written to localStorage, and the page keeps working with the network switched off.