HTTP status codes are a vital part of web browsing. Every request you make, every time you click on a link or enter a URL, you’ll get a response. Behind that response is a numeric code summarizing the result.

You’ve heard about the 404 code, and probably cursed your browser every time it shows one. But HTTP is more powerful than you might realize, and status codes handle many different scenarios. Read on to find out more about these cryptic little numbers.

How Web Clients and Servers Communicate

Web browsing is made possible by communication between clients and servers. When you ask to view a page, your client (browser) sends a request to a server (website). That request is hopefully successful, at which point the server sends a response for you to read.

In its response, the webserver includes more than just the content. For a start, it includes a series of headers, small pieces of metadata that apply to the response. For example, the Content-Type header might look like this:

        Content-Type: text/html; charset=UTF-8
    

This means “the response is HTML” as opposed to an image or a music file.

But before the content, before even the headers, every HTTP response includes a line that looks something like this:

        HTTP/1.1 200 OK
    

In this example, alongside the HTTP version (1.1), a status code reads “200 OK”. In other words, “everything is good, here’s your content.” The 200 is the most important bit. Systems can test against it to determine exactly what has occurred. The “OK” is a nice short hint, describing the status for any humans watching.

Examples of Common Status Codes

The 404 and 200 status codes are very common, but there are many more possibilities.

  • 500 (INTERNAL SERVER ERROR) is an error status. It means that something went wrong on the server and it cannot fulfill the request. This might be a programming bug or some other runtime error.
  • 403 (FORBIDDEN) means that the server understood the request but refuses to allow it. This often applies to user-related actions in more complicated web apps. For example, trying to edit a post that someone else owns.
  • 401 (UNAUTHORIZED) is very similar to 403. In this case, the original request is not allowed to access the resource because it didn’t provide any user credentials. In other words, you’re not logged in.
  • 400 (BAD REQUEST) means the server couldn’t understand what was being asked for. Maybe there’s some missing information, such as a URL parameter. Maybe something corrupted the request in transit.

HTTP Status Code Groups

All the status codes we’ve seen so far are three digits, all between 200 and 500. This is no coincidence. HTTP statuses are all three digits long, with the first digit between one and five, inclusive. And the value of that first digit puts the code into one of five groups, each with a specific meaning.

The first group, 1xx, is “informational”. These cases all mean that the server understood the request, but isn’t ready to send a response. You won’t see these in action much, but they’re there for systems that need them.

The 2xx group is the home of the response you usually want: 200 (OK). That’s the most common success case, but there are others.

The 204 (NO CONTENT) code is quite a strange one. A server can return it as a result of a PUT or a POST or a PATCH. The meaning, in these cases, would be that the server made the update, but there’s no need to return anything to the client.

Codes in the 3xx group demonstrate how HTTP statuses go beyond just communicating success or failure. Status codes beginning with a 3 indicate a redirection. This means the original request wasn’t bad, but the client should use a different URL instead.

This can be temporary, such as in the case of 302 (FOUND), which a site might use to host a promotional URL that redirects to a final product page. A site might use a permanent redirect instead, via the 301 (MOVED PERMANENTLY) status. This is good practice when, for example, a site has changed the name of a page.

Redirect statuses are usually accompanied by a Location header. This tells the client which URL to request instead of the original one. Servers will often respond with additional headers. These will provide more useful information than the status code alone.

Statuses beginning with a 4 are client errors. Essentially, they mean “the browser (or person using it) did something wrong”. We’ve already discussed several of these (400, 401, 403, 404), and this is the largest group of status codes by a significant amount. Other examples of client error include requesting a URL that used to exist but no longer does: 410 (GONE). There’s also 429 (TOO MANY REQUESTS), which supports rate-limiting so that resources don’t become overwhelmed. This is very commonly used by REST APIs.

Finally, statuses in the 500-599 range indicate something went wrong with the server whilst it tried to fulfill the request.

Getting HTTP Status With curl

The most commonly used, all-purpose HTTP command-line tool is curl. Using curl, you can send HTTP requests by hand, see underlying response details, and examine status codes.

The curl program doesn’t make it incredibly easy to show just a status code, but you can do so using a few options, namely:

  • -o <filename> tells curl to send its default output to a file. You can use it to discard all normal output.
  • -w <format> displays custom information from a set of available variables, one of which is “http_code”, i.e. the response status code.

You can also use -s to hide some details curl typically shows about the transfer, such as real-time progress. Here’s how to put these options together:

        $ curl -sw "%{http_code}" -o /dev/null http://example.org
200
$ curl -sw "%{http_code}" -o /dev/null http://bbc.co.uk
301

Or you can use slightly different options and a pipeline to manipulate the result:

        $ curl -sI http://example.org/no | head -1 | cut -f2 -d' '
404

Viewing Status Codes in a Web Browser

If you ever need to check HTTP status codes, your web browser can help out. Most modern browsers have a console that can display advanced information. Using Chrome as an example, here’s how to check a URL’s status code:

  1. Choose View -> Developer -> Developer Tools from the main menu. This toggles a small window at the bottom of your browser.
  2. If you’re not already looking at the Network tab of the Developer Tools window, change to it.
  3. Click the Doc button to show only requests for page content.
  4. Refresh the page you’re looking at.

Notice that, alongside requested URLs, the browser displays a Status column. It shows exactly which status code the server sent back.

A screenshot of GitHub's 404 page showing the HTTP status code in the browser's developer tools

Other Resources

There are plenty of good resources which explain more about HTTP status codes. The Wikipedia page titled List of HTTP status codes and this official datatracker standards document are good starting points.

The most useful reference might be httpstatuses.com. It explains all the HTTP status codes in a concise, easy-to-understand format. It also gives useful code details which can come in handy when programming anything to do with HTTP.

The format of httpstatuses’ URLs is particularly useful. The page for the 403 status code is simply https://httpstatuses.com/403. You can easily change the URL to look up any status code you need.

A screenshot of the httpstatuses.com website showing information about the 404 error

HTTP Statuses Make The Web Work

The HTTP status code is a simple three-digit number that most people experience in the guise of the 404. But it’s much more powerful than that, and status codes support a wide range of behavior.

HTTP2 is the next version of HTTP, but the good news is that status codes remain the same. Everything you’ve learned here will still be relevant for the foreseeable future.