SyntaxStudy
Sign Up
REST API 5xx Server Error Status Codes
REST API Beginner 1 min read

5xx Server Error Status Codes

The 5xx range indicates server-side errors—the request was valid but the server failed to fulfil it. 500 Internal Server Error is the generic fallback; 502 Bad Gateway means an upstream service returned an invalid response; 503 Service Unavailable indicates the server is temporarily unable to handle requests (overloaded or under maintenance). APIs should never expose stack traces or internal error details in 5xx responses—these are security risks. Instead, return a sanitised error message and a correlation ID (X-Request-ID) that can be used to look up the full error in server logs. Set the Retry-After header on 503 responses to tell clients when to retry.
Example
# 500 Internal Server Error — unexpected exception
HTTP/1.1 500 Internal Server Error
X-Request-ID: 7c4e2b1a-9f3d-4a8e-b0c5-123456789abc
{
  "error": "INTERNAL_ERROR",
  "message": "An unexpected error occurred. Reference ID: 7c4e2b1a",
  "requestId": "7c4e2b1a-9f3d-4a8e-b0c5-123456789abc"
}
# NEVER include: stack traces, SQL queries, file paths, internal IPs

# 502 Bad Gateway — upstream service (database, microservice) failed
HTTP/1.1 502 Bad Gateway
{ "error": "UPSTREAM_ERROR", "message": "Payment service unavailable" }

# 503 Service Unavailable — overloaded or maintenance
HTTP/1.1 503 Service Unavailable
Retry-After: 120
{ "error": "SERVICE_UNAVAILABLE", "message": "Scheduled maintenance. Back at 02:00 UTC" }

# 504 Gateway Timeout — upstream took too long
HTTP/1.1 504 Gateway Timeout
{ "error": "UPSTREAM_TIMEOUT", "message": "The request timed out. Please retry." }

# Laravel: global exception handler returning structured errors
// app/Exceptions/Handler.php
// public function render($request, Throwable $e): Response {
//   if ($request->expectsJson()) {
//     $status = $e instanceof HttpException ? $e->getStatusCode() : 500;
//     return response()->json([
//       'error'     => class_basename($e),
//       'message'   => app()->isProduction() ? 'Server error' : $e->getMessage(),
//       'requestId' => $request->header('X-Request-ID', Str::uuid()),
//     ], $status);
//   }
//   return parent::render($request, $e);
// }