AlgoMaster Logo

HTTP Status Codes

High Priority40 min readUpdated August 14, 2026
Listen to this chapter
Unlock Audio

An HTTP status code is the server's concise, machine-readable description of a response. It tells a client whether processing is still underway, the request succeeded, another request is needed, the client needs to change something, or the server failed.

The difference between two nearby codes can materially change client behavior. A 202 Accepted response does not mean that a background job finished. A 401 Unauthorized response asks for valid authentication credentials, while 403 Forbidden says the server refuses the request. A 307 Temporary Redirect preserves the original method, while a 302 Found response can turn a POST into a GET when followed by some user agents.

Status codes also shape production behavior. Load balancers aggregate them into health metrics, retry libraries use them to classify failures, caches attach special meaning to several of them, and monitoring systems often distinguish client problems from server problems using the first digit.

This chapter focuses on the codes backend engineers routinely emit, receive, and debug. The goal is not to memorize every registered value, but to choose the most precise standard code and understand what clients are entitled to infer from it.

The Status Line

An HTTP/1.1 response begins with a status line:

It contains:

The numeric code carries the standardized semantics. The reason phrase is optional, human-readable text. A client must not make decisions by matching phrases such as Not Found, because servers can omit, localize, or customize them.

HTTP/2 and HTTP/3 carry the numeric status in a :status pseudo-field rather than a textual status line. The meaning of 404 remains the same.

Valid HTTP status codes contain three digits from 100 through 599. The first digit identifies the response class:

RangeClassGeneral meaning
100–199InformationalProcessing is continuing; a final response will follow
200–299SuccessfulThe request was received, understood, and accepted
300–399RedirectionMore action or cached state is needed to complete handling
400–499Client ErrorThe request cannot be fulfilled as submitted
500–599Server ErrorThe server failed to fulfill an apparently valid request

The class is intentionally useful even when the exact code is unfamiliar. If a client receives an unrecognized 471, it still knows that it is a client-error response and handles it like a generic 400 rather than assuming success.

Values outside 100–599 are not HTTP status codes. Some libraries expose 0, 600, or other values for internal network errors, but those are library conventions rather than responses received from an HTTP server.

Interim and Final Responses

Most requests receive one final response from classes 2xx through 5xx. Before it, a server can send one or more 1xx interim responses:

An interim response ends after its header section. It cannot contain response content or trailers. A client must continue parsing until it receives the final response.

Do not record a 103 as the request's completed outcome or return to application code as though the operation finished. It is only progress information on the way to a final status.

Informational Responses: 1xx

Informational codes are less common than final codes, but three are important to recognize.

100 Continue

100 Continue allows a client to avoid sending a large request body before the server examines the request line and headers.

The client starts with:

If the server is willing to receive the body, it sends:

The client then transmits the content. A final response follows after processing.

The server can instead send a final error immediately—for example, when authentication fails or the declared size exceeds its limit. This saves the client from uploading bytes that the server already knows it will reject.

100 Continue is not the success result of the upload. It only says to proceed with the request content.

101 Switching Protocols

101 Switching Protocols confirms a protocol change requested through HTTP/1.1:

After the response's empty line, the connection follows the upgraded protocol. The bytes that follow are no longer an ordinary HTTP response body.

103 Early Hints

103 Early Hints lets a server send likely response fields while it is still preparing the final response:

A 4821-byte final response body is omitted from the illustration.

A browser can begin fetching the hinted resources before the final HTML is ready. The hints are speculative; they do not replace the fields in the final response, and the final status can still be an error.

Successful Responses: 2xx

A 2xx response means that the request was successfully received, understood, and accepted. It does not always mean that every related business process is finished.

200 OK

200 OK is the general success response. Its exact meaning depends on the request method.

For a GET, the content normally contains a representation of the target:

For a POST, the content might describe the result of processing. For a PUT or DELETE, it might describe the updated resource or operation result.

Do not use 200 merely because the server process returned a JSON document. This response is misleading:

Generic clients, monitoring systems, and proxies see a successful HTTP operation even though the application says it failed. Return a status code that reflects the HTTP outcome, then place application-specific detail in the response content.

201 Created

201 Created means that the completed request created one or more resources:

The primary created resource is identified by Location when that field is present. If Location is absent, the request target identifies it.

201 is appropriate only after creation succeeded. If a request merely entered a queue that might create a resource later, 202 Accepted is more accurate.

202 Accepted

202 Accepted means that the request was accepted for processing, but processing is incomplete:

The operation can still fail later. HTTP has no mechanism for the server to replace the already delivered 202 with a new final status after background work completes.

A useful asynchronous API therefore returns a way to inspect progress, such as an operation URI:

Returning 202 without a status resource, callback, event, or other completion mechanism leaves the client unable to learn the eventual outcome.

204 No Content

204 No Content means that the request completed successfully and there is no response content to send:

Response fields can still describe the target's new state. A 204 response ends after its header section and cannot contain content or trailers.

Use 204 when the client does not need a representation in the response. If the API wants to return an updated resource or operation result, use a success code that permits content instead.

206 Partial Content

206 Partial Content means the server successfully fulfilled a range request by returning only part of a selected representation:

The 1000 response-body bytes are omitted from the illustration.

A 206 response is not an ordinary truncated 200. Range metadata tells the client which bytes it received and how they relate to the complete representation.

Redirection Responses: 3xx

Redirection responses tell the client that another URI or previously stored representation is involved in completing the request.

Most redirects carry a Location field:

The difficult part is deciding what method the client uses for the next request.

CodeDuration or purposeMethod used when followed
301 Moved PermanentlyTarget has a new permanent URIHistorically, POST may become GET
302 FoundTarget temporarily resides elsewhereHistorically, POST may become GET
303 See OtherRetrieve an indirect result elsewhereUse GET, or retain HEAD
307 Temporary RedirectTemporary movePreserve the method and content
308 Permanent RedirectPermanent movePreserve the method and content

301 and 308: Permanent Moves

301 Moved Permanently and 308 Permanent Redirect both indicate a permanent new URI.

The difference is method handling. For historical compatibility, a user agent following 301 is allowed to change POST into GET. 308 requires the redirected request to preserve its method and content.

Use 308 when preserving the original operation is essential:

302 and 307: Temporary Moves

302 Found and 307 Temporary Redirect both describe a temporary alternate URI. Clients should continue using the original URI for future requests.

Again, method handling differs. A client may turn POST into GET after 302; it must preserve the method and content after 307.

303: Retrieve the Result Elsewhere

303 See Other intentionally directs the client to retrieve a different resource:

This is useful after a command or form submission when the server wants the next navigation to be a safe retrieval rather than a repeat of the original operation.

304: Not Modified

304 Not Modified is in the redirection class, but it is not a redirect to another URI. It answers a conditional GET or HEAD by telling the client that its stored representation is still usable:

A 304 response does not contain response content. The client reuses its stored content and updates relevant metadata from the response.

Do not return 304 merely because an update request made no changes. Its semantics are specifically tied to conditional retrieval.

Redirect Safety

Automatic redirect handling needs boundaries.

A client should cap redirect count to stop loops, resolve relative Location values correctly, and avoid forwarding credentials blindly to a different origin. 307 and 308 can replay a request body at the new location, so the client must be willing and able to resend that content.

Redirects do not make an unsafe operation safe. A redirected non-idempotent request still carries duplicate-effect risk if a failure makes the outcome ambiguous.

Client Error Responses: 4xx

A 4xx response means that the request cannot be fulfilled as submitted. The label “client error” does not mean the human user is necessarily at fault. Credentials can expire, rate limits can be temporary, and a resource can change between the client's read and write.

The response should explain whether and how the client can correct the request without exposing sensitive implementation details.

400 Bad Request

400 Bad Request is the general response for a request the server cannot or will not process because of a perceived client error:

Use 400 when the request itself cannot be interpreted reliably or no more specific standard code fits.

Avoid using it as the only error response for every rejected request. Authentication, missing resources, unsupported media types, conflicts, and rate limits have more informative codes.

401 Unauthorized

Despite its name, 401 Unauthorized means that the request lacks valid authentication credentials for the target.

The response must contain at least one authentication challenge:

Missing, expired, malformed, or otherwise invalid credentials commonly produce 401. A client might respond by obtaining or refreshing credentials and retrying.

403 Forbidden

403 Forbidden means that the server understood the request but refuses to fulfill it:

Sending the same credentials again does not solve a permission failure. If the server wishes to hide whether a forbidden resource exists, it can return 404 instead.

404 Not Found and 410 Gone

404 Not Found means that the origin server found no current representation for the target or is unwilling to disclose that one exists.

It does not say whether the absence is temporary or permanent:

410 Gone is more precise when the server knows that the resource was intentionally removed and the condition is likely permanent. Most APIs use 404 unless that permanence is useful to clients.

405 Method Not Allowed

405 Method Not Allowed means that the server recognizes the method, but the target resource does not support it:

The response must include Allow with the methods currently supported by that target.

This differs from 501 Not Implemented, where the server does not support the required functionality at all, such as an unrecognized method it cannot handle for any resource.

408 Request Timeout

408 Request Timeout means that the server did not receive a complete request within the time it was prepared to wait.

It does not mean that a gateway timed out waiting for an upstream response; that condition is 504 Gateway Timeout. It also differs from a client-side deadline expiring without any HTTP response.

409 Conflict

409 Conflict means that the request conflicts with the current state of the target resource and the client might be able to resolve that conflict:

The response should explain the conflict well enough for the client to decide whether to refresh state, change the request, or ask the user to resolve it.

412 Precondition Failed

412 Precondition Failed means that a condition supplied in the request evaluated to false:

If the current entity tag is now "profile-v8", the server rejects the update with 412 rather than applying it to an unexpected version.

Use 412 for a failed explicit HTTP precondition. Use 409 for a broader conflict with current resource state when no more specific precondition status applies.

413 Content Too Large

413 Content Too Large means that the request content exceeds a limit:

The older phrase “Payload Too Large” still appears in software, but the current registered name is Content Too Large.

414 URI Too Long

414 URI Too Long means that the request target is longer than the server is willing to interpret.

This can result from excessive query parameters, a redirect loop that repeatedly appends data, or placing a large structured query in the URI. It is different from 413, which concerns request content after the header section.

415 Unsupported Media Type

415 Unsupported Media Type means that the request content's format is not supported for that method and target:

If the endpoint accepts only JSON, 415 describes the format problem. The cause can also be an unsupported content encoding.

422 Unprocessable Content

422 Unprocessable Content means that the server understands the content type and the content is syntactically valid, but it cannot process the contained instructions:

The JSON parses correctly, but a negative quantity violates the operation's rules.

A practical distinction is:

425 Too Early

425 Too Early means that the server is unwilling to risk processing a request that might be replayed because it was sent using TLS early data.

A client that used early data should retry after the handshake completes, without using early data for the retry. This code has a narrow replay-protection purpose; it is not a general “please wait” response.

428 Precondition Required

428 Precondition Required means that the origin requires the request to be conditional:

This helps an API require optimistic concurrency protection instead of accepting writes that can silently overwrite another client's update.

428 says a condition is missing. 412 says a supplied condition evaluated to false.

429 Too Many Requests

429 Too Many Requests means that the client exceeded a rate limit:

The limit might be scoped by account, API key, IP address, operation, or another policy. A Retry-After field can tell the client how long to wait.

Use 429 for rate limiting associated with the caller or request policy. 503 Service Unavailable is usually a better signal when the service as a whole is temporarily unable to accept work.

431 Request Header Fields Too Large

431 Request Header Fields Too Large means that the server refuses to process the request because one header field or the combined header section is too large.

Oversized cookies, long authorization tokens, and excessive tracing baggage are common causes. This differs from 413, which limits request content, and 414, which limits the target URI.

Other Useful 4xx Codes

Some less frequent codes are still worth recognizing.

406 Not Acceptable means that the server cannot produce a representation acceptable under the client's content-negotiation preferences and will not send a default.

416 Range Not Satisfiable means that the requested ranges cannot be satisfied for the selected representation.

421 Misdirected Request means that the server cannot provide an authoritative response for the target in the current connection context. A client can retry it on a different, target-specific connection.

426 Upgrade Required means the server refuses the current protocol but might serve the request after an indicated protocol upgrade.

451 Unavailable For Legal Reasons indicates that access is denied because of a legal demand or restriction.

Server Error Responses: 5xx

A 5xx response means that the server failed to fulfill an apparently valid request. “The server” might be the origin application, reverse proxy, API gateway, load balancer, or CDN that generated the response.

500 Internal Server Error

500 Internal Server Error is the general response for an unexpected server condition:

Expected domain failures should not become 500. An invalid order quantity is a client-facing validation failure, not an internal server malfunction.

The response should give the client a stable error description and correlation identifier where useful. Stack traces, SQL statements, credentials, internal hostnames, and other implementation details belong in protected server logs rather than the public response.

501 Not Implemented

501 Not Implemented means that the server does not support the functionality required to fulfill the request.

For methods, the distinction is:

Do not use 501 for a feature that is temporarily disabled or unfinished when the server otherwise recognizes and implements the operation's protocol semantics.

502 Bad Gateway

502 Bad Gateway means that a server acting as a gateway or proxy received an invalid response from an upstream server.

Examples include an upstream closing the connection before producing a valid response or returning malformed protocol data. If the origin successfully returns a well-formed 500, the gateway normally forwards that 500; it should not relabel every upstream application failure as 502.

503 Service Unavailable

503 Service Unavailable means that the server is temporarily unable to handle the request, commonly because of overload or maintenance:

Retry-After can suggest when the client should try again. The absence of 503 does not prove the service was healthy: a severely overloaded server might refuse the connection before it can send any HTTP response.

504 Gateway Timeout

504 Gateway Timeout means that a gateway or proxy did not receive a timely response from an upstream server needed to complete the request.

A 504 does not prove that the upstream performed no work. The upstream might commit an operation after the gateway stops waiting. Retrying a non-idempotent request therefore requires the same duplicate-effect precautions as any other ambiguous outcome.

Sometimes There Is No HTTP Status

An HTTP status code exists only when some HTTP server sends a parseable response.

These failures can occur without one:

Libraries often map these conditions to exceptions, error objects, or synthetic numbers such as status 0. They are not 500 or 504 responses because no HTTP status was received.

This distinction matters during debugging:

Operational dashboards should separate transport failures from HTTP response classes. Combining them all under “5xx” hides where the failure occurred.

Status Codes and Structured Error Content

A status code gives generic protocol semantics. It cannot express every application-specific detail.

For machine-readable HTTP API errors, the Problem Details format uses:

For example:

The standard members have distinct purposes:

type is a stable URI identifying the category of problem. Clients should use this—not the human text—as the primary problem identifier.

title is a short, human-readable summary of that problem type.

status repeats the HTTP status for convenience. It should agree with the actual response status, which generic HTTP components see.

detail describes this occurrence for a human.

instance identifies this particular occurrence, often so it can be correlated with support or logs.

Extensions such as errors can add domain-specific structured data.

Do not force clients to parse an English detail string to discover which field failed. Provide stable problem types and structured extension members.

Problem details are an interface error format, not a debugging dump. Avoid exposing stack traces, database queries, filesystem paths, secrets, or internal topology.

Deciding Whether to Retry

Status code is one input to a retry decision, not the entire decision.

Codes that often represent temporary conditions include:

Even then, an automatic retry should proceed only when:

  • Repeating the request is safe for the operation.
  • The request content can be sent again.
  • The client's overall deadline and retry budget allow another attempt.
  • The delay respects Retry-After when supplied.
  • Backoff and jitter prevent synchronized retry storms.

Most unchanged 400, 403, 404, 405, 413, 415, and 422 requests should not be retried automatically. The client must change the request, credentials, permissions, or target first.

Some codes invite a corrective action rather than a blind retry:

A response can be retryable while the operation is not. For example, 504 is often temporary, but automatically repeating an unprotected payment POST can create a duplicate charge.

Choosing a Status Code for an API

Start with the outcome rather than choosing a favorite number.

For successful requests:

For rejected requests:

For server failures:

Use the most specific standard code whose semantics match. Put finer domain detail in a structured response rather than inventing a new status code for every business rule.

Consistency matters across endpoints. If one service returns 404 for a missing order while another returns 200 with an error envelope, shared clients and observability tools need special cases for behavior that HTTP already standardizes.

Loading simulation...

Status Codes in Production Debugging

The component that returns a response might not be the component that failed.

A CDN can generate 403, 429, 502, or 503 before the request reaches the origin. An API gateway can generate 401 after rejecting credentials. A reverse proxy can generate 504 while the application continues working. The application's own status might also be transformed by an intermediary.

Useful request telemetry records:

  • Method and normalized route template
  • Final HTTP status code
  • Status code from each upstream hop where available
  • Total latency and upstream latency
  • Retry count
  • A correlation or trace identifier
  • Which component generated the response

Use a route template such as /orders/{id} for metrics rather than a raw target such as /orders/781. Raw identifiers create high-cardinality metrics and can expose sensitive information.

Monitor status classes, but keep enough detail to distinguish causes. A sudden increase in 401 suggests a different problem from an increase in 429. A rise in gateway-generated 504 calls for different investigation than application-generated 500.

Do not assume every 4xx is harmless to service health. A wave of 429 can indicate overload, repeated 401 responses can reveal an authentication incident, and malformed-request spikes can indicate abusive traffic.

Common Misunderstandings

A status code is not merely decoration around a JSON body. Generic HTTP components primarily understand the code, not an application-specific success field.

200 with an error object is still HTTP success. Return a fitting error status when the HTTP operation failed.

202 means accepted, not completed. The eventual operation can still fail and needs a separate outcome mechanism.

204 cannot carry response content. Use another success response when the client needs a body.

206 is not a generic partial success code. It specifically describes successful range transfer.

301 and 302 do not guarantee method preservation. Use 307 or 308 when the redirected request must retain its method and content.

304 is not an empty 200 and not a generic “unchanged” result. It tells a conditional retrieval to reuse stored content.

401 is about authentication. Its historical phrase is misleading, and the response must include an authentication challenge.

403 is not a substitute for every client error. It means the server understood the request and refuses it.

404 can conceal a forbidden resource. It does not always prove that no underlying resource exists.

405 and 501 are different. One rejects a known method for a particular target; the other lacks required functionality server-wide.

409 is about conflict with current state. 422 is better for syntactically valid content whose instructions cannot be processed.

412 means a supplied HTTP precondition failed. 428 means the server requires a condition that was not supplied.

The current name of 413 is Content Too Large. Older software may still display Payload Too Large.

429 and 503 describe different scopes. One normally represents rate limiting for a caller or policy; the other represents temporary service unavailability.

A gateway-generated 504 does not prove the upstream did nothing. The upstream can finish after the gateway's deadline.

A client timeout is not automatically a 504. If no HTTP response arrived, there is no status code.

Not every 5xx request should be retried. The operation must be repeat-safe, the failure plausibly temporary, and the retry budget available.

Reason phrases are not stable programmatic values. Use the numeric code and structured content.

Unrecognized status codes still have a recognizable class. A client can handle an unknown 4xx as a generic client error.

Summary

HTTP status codes from 100 to 599 describe informational, successful, redirection, client-error, and server-error outcomes. 1xx is interim; one final 2xx–5xx response follows. Common successes include 200 general success, 201 creation, 202 asynchronous acceptance, 204 no content, and 206 a range response.

For redirects, 301 and 302 may change POST to GET, while 307 and 308 preserve method and content. 303 retrieves an indirect result, and 304 reuses validated cached content.

Client errors distinguish malformed (400), authentication required (401), forbidden (403), reported or concealed absence (404), disallowed method (405), conflict (409), failed or required preconditions (412, 428), unsupported media (415), unprocessable instructions (422), oversized content, URI, or headers (413, 414, 431), and rate limiting (429). Server-side codes include unexpected failure (500), unsupported functionality (501), bad upstream response (502), temporary unavailability (503), and upstream timeout (504).

DNS, TCP, TLS, or client timeout failures may produce no HTTP status. Problem Details adds domain-specific errors, while retries must consider idempotency, replayable content, Retry-After, backoff, jitter, and budgets.

Use the most specific standard status for protocol semantics and structured content for domain detail.

Quiz

HTTP Status Codes Quiz

5 quizzes