HTTP status code reference
Every HTTP status code explained in plain English — what it means, what causes it, and how to send it in PHP. Click any code to expand.
The server has received the request headers and the client should proceed to send the request body. Used when the client wants to check if the server will accept a request before sending a large body.
Common causes: Client sent Expect: 100-continue header before sending a POST body.
The server agrees to switch protocols as requested by the client. Commonly used when upgrading an HTTP connection to WebSocket.
Common causes: Client sent Upgrade: websocket header.
Allows the server to send preliminary response headers before the final response. Used to preload resources while the server is still preparing the main response.
Common causes: Server-side optimisation for critical resource hints (Link: headers).
The request succeeded. The response body contains the requested resource. This is the standard success response for GET, POST, PUT, PATCH.
Common causes: Everything worked correctly.
http_response_code(200); // default for most responsesThe request succeeded and a new resource was created. Should include a Location header pointing to the new resource. Use this for successful POST requests that create something.
Common causes: Client POSTed data that created a new record or resource.
http_response_code(201);The request has been accepted for processing, but processing has not been completed. Use when a task is queued or running asynchronously.
Common causes: Request queued for background processing (e.g. sending an email, generating a report).
http_response_code(202);The server successfully processed the request but has no content to return. Commonly used for DELETE requests or form submissions where no redirect is needed.
Common causes: Successful DELETE, or PUT/PATCH that returns nothing.
http_response_code(204); exit;The server is delivering only part of the resource due to a Range header sent by the client. Used for resumable downloads and video streaming.
Common causes: Client sent a Range: bytes=0-1023 header to request part of a file.
// Set manually with Range header supportThe resource has permanently moved to a new URL. Browsers and search engines update their records. The new URL is given in the Location header. Use for permanent URL changes.
Common causes: Page moved to a new URL permanently (e.g. domain change, URL restructure).
header("Location: https://new-url.com", true, 301); exit;The resource is temporarily at a different URL. Browsers follow the redirect but don't update bookmarks. Search engines don't transfer ranking. Often misused when 301 is intended.
Common causes: Temporary redirect — login required, maintenance page, A/B testing.
header("Location: /login", true, 302); exit;After a POST request, redirect the browser to a GET request at the given URL. The correct redirect to use after a form submission to prevent double-submit on refresh.
Common causes: Post/Redirect/Get (PRG) pattern after form processing.
header("Location: /success", true, 303); exit;The resource has not changed since the client's cached version. The client should use its cache. No body is sent. Reduces bandwidth.
Common causes: Client sent If-Modified-Since or If-None-Match header and content hasn't changed.
http_response_code(304); exit;Like 302 but guarantees the method and body will not change on the redirected request. POST stays POST. Use when you must redirect a POST temporarily.
Common causes: Temporary redirect where the HTTP method must be preserved.
header("Location: /new-endpoint", true, 307); exit;Like 301 but preserves the HTTP method. POST to /old stays POST to /new. Use for permanent API endpoint changes.
Common causes: Permanent redirect where the HTTP method must be preserved.
header("Location: /new-endpoint", true, 308); exit;The server cannot process the request due to a client error — malformed syntax, invalid parameters, missing required fields, or invalid JSON. The client should not repeat the request without modification.
Common causes: Missing required fields, invalid JSON body, malformed query parameters, type mismatch.
http_response_code(400); echo json_encode(["error" => "Bad request"]);Authentication is required and has failed or not been provided. Despite the name, this is about authentication (proving who you are), not authorisation. The client may retry with credentials.
Common causes: Missing or invalid API key, expired JWT token, wrong username/password.
http_response_code(401); header("WWW-Authenticate: Bearer");The server understood the request but refuses to authorise it. Unlike 401, authentication won't help — the client simply doesn't have permission. Don't reveal whether a resource exists if that's sensitive.
Common causes: Correct credentials but insufficient permissions, IP blocked, file permissions wrong, directory listing disabled.
http_response_code(403); exit;The server cannot find the requested resource. May be used deliberately to hide the existence of a resource (instead of 403). The most common error on the web.
Common causes: Wrong URL, deleted page, mistyped route, missing file, broken link.
http_response_code(404); include "404.php"; exit;The HTTP method is not supported for this endpoint. The response must include an Allow header listing the supported methods.
Common causes: Sending POST to a GET-only endpoint, or DELETE to a read-only resource.
http_response_code(405); header("Allow: GET, POST");The server timed out waiting for the complete request from the client. The client can repeat the request.
Common causes: Slow client, large file upload on a slow connection, network issues.
http_response_code(408);The request conflicts with the current state of the resource. Common in APIs when a resource already exists or a version conflict occurs.
Common causes: Duplicate entry (unique constraint), optimistic locking conflict, editing a deleted record.
http_response_code(409); echo json_encode(["error" => "Conflict"]);The resource is permanently gone and will not be available again. Stronger than 404 — tells search engines to remove the URL from their index.
Common causes: Content intentionally deleted and never coming back.
http_response_code(410); exit;The request body is larger than the server is willing to process. Often caused by upload size limits in PHP or Nginx.
Common causes: File upload exceeds upload_max_filesize or post_max_size in php.ini, or client_max_body_size in Nginx.
http_response_code(413);The server refuses to accept the request because the payload format (Content-Type) is unsupported.
Common causes: API expects application/json but client sent text/plain, or vice versa.
http_response_code(415);Non-standard Laravel/Symfony code returned when a CSRF token is missing or expired. The session has expired and the form needs to be resubmitted.
Common causes: CSRF token missing from form, session expired, form submitted twice.
// Laravel returns this automatically on CSRF failureThe request was well-formed but contains semantic errors. The server understands the content type and syntax, but can't process the instructions. Common in REST APIs for validation failures.
Common causes: Validation failed — e.g. email format invalid, required field blank, value out of range.
http_response_code(422); echo json_encode(["errors" => $validation_errors]);The client has sent too many requests in a given time window (rate limiting). Include a Retry-After header to tell the client when to try again.
Common causes: Rate limit exceeded on an API, DDoS protection triggered, brute force protection.
http_response_code(429); header("Retry-After: 60");A generic server-side error. Something went wrong on the server that it can't be more specific about. The most common server error — often a PHP fatal error, database connection failure, or misconfiguration.
Common causes: PHP fatal error, uncaught exception, wrong file permissions, database connection failed, syntax error in config.
http_response_code(500); // PHP throws this automatically on fatal errorsThe server does not support the functionality required to fulfill the request. The server doesn't recognise the request method or lacks the ability to fulfill it.
Common causes: Client used an HTTP method the server doesn't support (e.g. PATCH on an old server).
http_response_code(501);The server acting as a gateway or proxy received an invalid response from an upstream server. Often seen when Nginx can't reach PHP-FPM or an app server.
Common causes: PHP-FPM is down or crashed, upstream app server not running, socket connection failed, wrong proxy address in Nginx config.
// Returned by Nginx/Apache — not set in PHPThe server is temporarily unable to handle the request — overloaded or down for maintenance. Include a Retry-After header. Search engines will not remove the URL if this is temporary.
Common causes: Server overloaded, maintenance mode, PHP-FPM pool exhausted, database server down.
http_response_code(503); header("Retry-After: 3600");The server acting as a gateway did not receive a timely response from an upstream server. Like 502 but specifically a timeout rather than an invalid response.
Common causes: PHP script took too long, upstream API timeout, database query too slow, max_execution_time exceeded.
// Returned by Nginx/Apache when PHP-FPM times outThe server does not support the HTTP protocol version used in the request.
Common causes: Very rare — client or proxy using an unsupported HTTP version.
http_response_code(505);REST API design, proper status codes, authentication, and error handling — covered in our PHP developer ebooks.