HTTP Status Codes and Error Handling

By the Syncfusion DevTutorials team · Last updated

Make every reply tell the truth: choose the right status code, stop hiding errors inside 200 OK, and send errors as Problem Details (RFC 9457).

A status code is a three-digit number that the server sends back with every HTTP response. It tells the client whether the request was successful or whether something went wrong.

Status codes give a quick summary of the result before the client reads the response body. They help applications, browsers, and developers understand what happened and decide what to do next.

For example, 200 OK means the request succeeded, 404 Not Found means the requested resource does not exist, and 500 Internal Server Error means something failed on the server. Using the correct status code makes APIs easier to use, troubleshoot, and maintain.

Watch the App Say "Success!"

Ravi orders a pizza. Brew & Bytes does not sell pizza.

Then Priya orders zero lattes.

Both times, the app shows a green "Success!" message.

Program.cs — every reply is 200 OK

Both responses return: 200 OK

The actual error is hidden inside the response body: {"success": false}

The app only checks the status code, sees 200, and assumes everything worked.

In simple words: the status code does not match the real result. Clients should not have to search through the response body to discover whether a request failed. The status code should clearly describe the outcome.

TL;DR

  • Status codes are grouped into families.
  • 2xx means the request succeeded.
  • 4xx means the client made a mistake.
  • 5xx means the server failed.
  • 200 OK means success.
  • 201 Created means something new was created.
  • 204 No Content means the request succeeded and there is no response body.
  • 400 Bad Request means the request is invalid.
  • 404 Not Found means the resource does not exist.
  • 409 Conflict means the request conflicts with the current state.
  • 422 Unprocessable Entity means the request is valid but cannot be completed.
  • 500 Internal Server Error means something failed on the server.
  • Never return 200 OK for an error.
  • Use Problem Details to provide a standard format for error responses.

A Real-World Example

Think about ordering coffee at a café.

The staff might respond with "Here is your latte." That is a success (200). They might say "Your order has been placed. Order number 101." That means something was created (201). "We don't sell that item." is a client mistake (4xx). "Our coffee machine is broken." is a server problem (5xx).

You know the result immediately from the first sentence.

Status codes give applications that same quick understanding.

The first digit identifies the status family: 2xx success, 3xx redirect, 4xx client error, and 5xx server error.

What You Will Learn

In this lesson, you will learn:

  1. The five status-code families.
  2. The most common status codes and when to use them.
  3. Why returning 200 for errors causes problems.
  4. How to use Problem Details for error responses.
  5. How applications can react to different status codes.

Let the Status Code Speak

The following example returns status codes that match the real result.

Program.cs — honest status codes

SituationStatus Code
Order created successfully201 Created
Quantity is 0400 Bad Request
Item does not exist on the menu422 Unprocessable Entity
Order exists200 OK
Order does not exist404 Not Found

Now the application can determine the result simply by looking at the status code.

No guessing is required.

400 or 422?

Both indicate that the client made a mistake.

Use 400 Bad Request when the request itself is invalid. Examples are missing required fields, invalid JSON, and invalid values.

Use 422 Unprocessable Entity when the request is valid but cannot be completed. Examples are ordering an item that does not exist, and requesting an action that violates business rules.

Many APIs use only 400. The important thing is to follow the same rule consistently throughout the API.

Choose the status code by identifying where the problem occurred. If there is no problem, the request succeeded.

A 4xx means "the client can fix this": change the request and try again. A 5xx means "this is not your fault": the client can only wait and retry. Getting the family right tells the client what to do next.

Problem Details: A Standard Error Format

The status code explains the type of error. The response body should explain the details.

Problem Details is a standard JSON structure used for API errors.

Common fields include:

FieldPurpose
typeA link describing the error type
titleA short summary of the error
statusThe HTTP status code
detailA detailed explanation of the problem
errorsValidation errors grouped by field

Problem Details responses use the content type: application/problem+json

This tells clients that the response contains error information.

Problem Details provides a standard structure for API error responses.

Program.cs — errors as Problem Details

For validation errors, the response looks like this: {"errors": {"quantity": ["Quantity must be greater than zero."]}} The application immediately knows which field caused the problem. For other errors, the API can provide a clear title, a detailed explanation, and the correct status code.

In ASP.NET Core, helpers such as:

Results.ValidationProblem(...)
Results.Problem(...)

can generate Problem Details automatically.

409 Conflict

Sometimes a request is valid, but it cannot be completed because of the current state of the resource. Example: an open order can be cancelled, but a delivered order cannot be cancelled.

Program.cs — 409 Conflict

An open order returns 200 OK. A delivered order returns 409 Conflict. A missing order returns 404 Not Found. The request itself is valid. The problem is that the current state does not allow the operation.

Never return 200 for an error. Clients, browsers, caches and monitoring tools all trust the status code. A 200 with "success": false inside looks like success to every one of them. Dashboards stay green while customers fail.

The Client's Side

Clients should react differently depending on the status code.

StatusMessages.cs — the app reacts to the code

Typical behavior:

Status CodeClient Response
200Show the data
201Show success and the new resource
400Ask the user to fix the input
404Show "Not Found"
409Explain the conflict
5xxShow "Please try again later"

Most applications handle all server errors (5xx) in a similar way because users cannot fix them.

Do not put internal details in an error, like stack traces, SQL or file paths. They help attackers and confuse customers. Write a clear title and detail, and log the technical details on the server.

Where You See This

  • Mobile apps show different screens for authentication errors, missing data, and server failures.
  • Monitoring tools use 5xx responses to detect outages.
  • Browsers and API clients rely on status codes before reading response bodies.
  • ASP.NET Core and many other frameworks support Problem Details automatically.

Common mistakes

SymptomCauseFix
The app shows "Success!" for a failed orderThe API returns 200 with the error in the bodyReturn the right 4xx
The app cannot find a new order201 is sent without a Location headerAdd Location: /orders/{id}
Monitoring shows no errors during an outageServer failures are sent as 200Let real failures be 5xx
Users see stack tracesThe text of the exception goes into the responseSend Problem Details with a plain title, and log the rest

Exercises

What to Remember

  • The status code tells the client what happened, before it reads the body.
  • 2xx worked, 4xx is a client mistake, 5xx is a server mistake.
  • Use 201 + Location for something new, 404 for missing, 409 for a clash, and 400/422 for bad input.
  • Send errors as Problem Details, application/problem+json.
  • Never return 200 for an error.

Next: Request Validation and DTOs. You will stop bad data before it reaches the database.