HTTP Status Codes
HTTP status codes communicate whether an HTTP request succeeded, was redirected, or failed. Frontend engineers commonly use them to decide how `fetch()` responses should be handled.
An HTTP status code is a three-digit number sent by a server in its response. The first digit identifies the broad class: `2xx` indicates success, `3xx` indicates redirection, `4xx` indicates a client-side request problem, and `5xx` indicates a server-side problem.
Common success codes include `200 OK` for a successful request and `201 Created` when a request creates a resource. `204 No Content` means the request succeeded but the response has no body, which is useful for operations such as successful deletion or updates that return no representation.
`3xx` responses deal with redirection or cached-resource behavior. For example, `301 Moved Permanently` and `302 Found` indicate redirects, while `304 Not Modified` tells a client that a cached representation can still be used. Browsers and HTTP clients may follow redirects automatically depending on the request and client configuration.
`4xx` responses generally mean the request cannot be fulfilled because of something associated with the client request. `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, and `429 Too Many Requests` are especially common in frontend applications. A `401` concerns authentication, whereas `403` indicates that the server understood the request but will not authorize it.
`5xx` responses indicate that the server encountered an error while attempting to handle the request. `500 Internal Server Error` is the common generic server-error response, while `502 Bad Gateway` and `503 Service Unavailable` can indicate problems involving an upstream service or temporary server unavailability.
Key points
- `2xx` means the request was successfully processed.
- `3xx` represents redirection or cache-related conditions.
- `4xx` generally indicates a problem with the request or its authorization.
- `5xx` indicates a server-side failure while processing the request.
- With `fetch()`, an HTTP error such as `404` does not by itself cause the promise to reject; inspect `response.ok` or `response.status`.
Interview questions
What do the five HTTP status-code classes mean?
The first digit identifies the broad category of the response. `2xx` represents success, `3xx` represents redirection or related cache behavior, `4xx` generally represents a client/request problem, and `5xx` represents a server-side failure. The exact meaning still depends on the individual status code.
What is the difference between 401 and 403?
`401 Unauthorized` indicates that the request lacks acceptable authentication credentials or needs authentication. `403 Forbidden` indicates that the server understood the request but refuses to authorize the requested action. In practice, a frontend might respond to `401` by asking the user to authenticate, while `403` can indicate insufficient permissions.
Does fetch() reject its promise when an API returns 404 or 500?
No. A normal HTTP response such as `404` or `500` still produces a fulfilled `fetch()` promise. The response should be inspected with properties such as `response.ok` and `response.status`. A rejected promise generally represents a failure to complete the fetch operation itself, such as a network-level failure, rather than an ordinary HTTP error response.
When would an API return 201 or 204 instead of 200?
`201 Created` is appropriate when a request successfully creates a new resource. It can be accompanied by information describing the created resource and commonly identifies the new resource through a `Location` header. `204 No Content` indicates successful processing when the server intentionally has no response body to return. The choice communicates useful information about what happened, rather than merely indicating generic success.
How should a frontend handle different HTTP status codes?
The frontend should map statuses to user-visible and application-level behavior rather than treating every non-2xx response identically. Authentication failures may trigger an authentication flow, authorization failures may show a permissions message, validation errors may display field-level feedback, and transient server or rate-limit responses may support retry behavior when appropriate. The implementation should also distinguish HTTP responses from network failures and avoid exposing raw server details to users. Error handling should be consistent across API clients so individual components do not each invent their own rules.