DEV Community

Juma Evans
Juma Evans

Posted on

HTTP Status Codes

You send a request to an API.

Sometimes everything works:

200 OK

Sometimes you made a mistake:

404 Not Found

And sometimes the problem isn't yours at all:

500 Internal Server Error

These three-digit numbers are HTTP status codes.

They are one of the simplest ways for a server to tell a client what happened to its request.

But with dozens of possible status codes, do you really need to memorize all of them?

Probably not.

As a backend developer, you should understand the important ones and, more importantly, know when to use them.

Let's break them down.


The Five HTTP Status Code Categories

HTTP status codes are grouped into five categories:

Range| Category| Meaning
"1xx"| Informational| Something is happening
"2xx"| Success| The request worked
"3xx"| Redirection| The client needs to go somewhere else
"4xx"| Client Error| Something is wrong with the request
"5xx"| Server Error| Something went wrong on the server

The first digit tells you the general story.

For example:

2xx → Good
3xx → Go somewhere else
4xx → Check your request
5xx → Check the server

Now let's look at the ones we actually encounter more often.


200 OK

The classic.

200 OK

It means:

«The request was successfully processed.»

For example:

GET /users/42

might return:

HTTP/1.1 200 OK

{
"id": 42,
"name": "Evans"
}

If you're requesting data and everything went well, "200 OK" is usually what you expect.


201 Created

This one is especially important when building APIs.

201 Created

It means:

«The request successfully created a new resource.»

For example:

POST /users

creates a new user.

Instead of returning:

200 OK

you can return:

201 Created

to tell the client:

«"Your request succeeded, and something new was created."»

For REST APIs, this is commonly used after successful "POST" requests.


204 No Content

Sometimes the request succeeds, but there's nothing to send back.

That's where:

204 No Content

comes in.

A common example is deleting something:

DELETE /users/42

The server successfully deletes the user, but doesn't need to return a response body.

So:

204 No Content

is perfectly appropriate.

Think:

«Success, but there's nothing to return.»


301 and 302: Redirects

Now we enter the "3xx" category.

These codes tell the client:

«"The resource you're looking for is somewhere else."»

301 Moved Permanently

The resource has permanently moved to another location.

For example:

http://example.com

https://example.com

A browser can follow the redirect automatically.

302 Found
This also redirects the client, but traditionally represents a temporary redirect.

You don't need to memorize every nuance immediately.

The important idea is:

3xx → The client needs to follow a different path.


400 Bad Request

Now we get to the codes backend developers see constantly.

400 Bad Request

It generally means:

«The server couldn't process the request because the request itself was invalid.»

Imagine your API expects:

{
"age": 26
}

But the client sends:

{
"age": "twenty-six"
}

The server may respond with:

400 Bad Request

Other examples include:

  • malformed JSON
  • invalid request parameters
  • missing required information
  • invalid request syntax

The important distinction is:

«The client sent something the server couldn't reasonably process.»


401 Unauthorized

This one is commonly misunderstood.

401 Unauthorized

usually means:

«Authentication is required or the provided authentication credentials are invalid.»

For example:

GET /profile
Authorization: Bearer invalid-token

The server might respond:

401 Unauthorized

Think:

«"Who are you?"»

This is about authentication.


403 Forbidden

Now compare that with:

403 Forbidden

This generally means:

«The server understands who you are, but you aren't allowed to access this resource.»

For example:

User → authenticated ✓
User → administrator ✗

The user might be logged in but still unable to access:

/admin/users

So a useful mental model is:

401 → You haven't successfully authenticated.
403 → You're authenticated, but you're not allowed.

That distinction is extremely useful when designing APIs.


404 Not Found

Probably the most famous HTTP status code.

404 Not Found

It means:

«The requested resource could not be found.»

For example:

GET /users/999999

If that user doesn't exist:

404 Not Found

It can also happen when a route doesn't exist:

GET /something-that-does-not-exist

The server is essentially saying:

«"I don't have what you're asking for."»


405 Method Not Allowed

Here's another useful one.

Suppose an endpoint supports:

GET /users

but doesn't support:

DELETE /users

The server may respond:

405 Method Not Allowed

The resource exists.

The problem is the HTTP method being used.

Think:

«"You're knocking on the right door, but you're using the wrong way to ask."»


429 Too Many Requests

This one becomes particularly important when dealing with APIs.

429 Too Many Requests

means the client has sent too many requests in a given period.

For example, an API might allow:

100 requests per minute

If a client sends 500 requests in a minute, the server might respond:

429 Too Many Requests

This is commonly associated with rate limiting.

It helps protect services from:

  • accidental request floods
  • abusive clients
  • poorly designed applications
  • certain automated attacks

This is also one reason rate limiting is an important backend concept.


500 Internal Server Error

Now we've reached the "5xx" category.

500 Internal Server Error

This generally means:

«Something went wrong while the server was processing the request.»

For example, your application might encounter an unexpected error:

Request

Go API

Database query

Unexpected failure

500

The important thing to understand is that "500" isn't supposed to mean:

«"The user did something wrong."»

It's a server-side failure.

As a developer, seeing lots of "500" responses should make you start checking:

  • application logs
  • database connections
  • dependencies
  • configuration
  • unexpected exceptions
  • recent deployments

502 Bad Gateway

This one becomes particularly interesting when you have reverse proxies.

Having this architecture in mind:

Client

Nginx(reverse proxy)

Backend

What happens if Nginx tries to communicate with your backend and receives an invalid response?

You might see:

502 Bad Gateway

Think:

«"The server acting as a gateway/proxy received a bad response from another server."»

This is one reason you'll sometimes see:

502 Bad Gateway

when an application behind Nginx is down or misconfigured.


503 Service Unavailable

means the server is currently unable to handle the request.

Possible reasons include:

  • server overload
  • maintenance
  • temporary unavailability
  • unavailable dependencies

For example:

Load Balancer

├──► Server A ✓
├──► Server B ✗
└──► Server C ✗

If there aren't enough healthy servers to handle requests, a service might return:

503 Service Unavailable

It's often a signal that the problem may be temporary.


504 Gateway Timeout

And finally:

504 Gateway Timeout

This usually means a gateway or proxy waited too long for another server to respond.

For example:

Client

Nginx

Backend

Database

... taking too long ...

Eventually:

504 Gateway Timeout

This can be a useful clue when debugging slow services.


A Simple Cheat Sheet

You don't need to memorize everything.

Start with these:

Code| Meaning| Think
"200"| OK| It worked
"201"| Created| Something was created
"204"| No Content| It worked, nothing to return
"301"| Moved Permanently| New permanent location
"302"| Found/Redirect| Go somewhere else
"400"| Bad Request| Your request is invalid
"401"| Unauthorized| Authenticate
"403"| Forbidden| You're not allowed
"404"| Not Found| Resource doesn't exist
"405"| Method Not Allowed| Wrong HTTP method
"429"| Too Many Requests| Slow down
"500"| Internal Server Error| Server failed
"502"| Bad Gateway| Upstream response problem
"503"| Service Unavailable| Server can't handle this now
"504"| Gateway Timeout| Upstream took too long


One More Important Thing

A status code is not just something your framework generates.

As a backend developer, you choose appropriate status codes.

For example, imagine you're writing a Go API:

if user == nil {
http.Error(w, "User not found", http.StatusNotFound)
return
}

You're communicating something important to the client:

The server is working.
The request was understood.
But the requested resource doesn't exist.

That's much more useful than returning:

500 Internal Server Error

for every possible problem.

Good APIs communicate clearly.


Final Takeaway

HTTP status codes are essentially a language between clients and servers.

You don't need to memorize every status code ever created.

Start by understanding the categories:

1xx → Information
2xx → Success
3xx → Redirection
4xx → Client problem
5xx → Server problem

Then remember the most useful ones:

200 → OK
201 → Created
204 → No Content

400 → Bad Request
401 → Authentication required
403 → Forbidden
404 → Not Found
405 → Method Not Allowed
429 → Too Many Requests

500 → Server Error
502 → Bad Gateway
503 → Service Unavailable
504 → Gateway Timeout

The next time you see:

HTTP/1.1 404 Not Found

don't just think "something went wrong."

Ask:

«Who is responsible for this response, what does it communicate, and what should happen next?»

That's when HTTP status codes stop being numbers and start becoming useful tools for building and debugging backend systems.

Top comments (0)