HTTP Status Codes and MIME Types, Explained

By Udit Agarwal · Updated October 17, 2026

An HTTP status code is the three-digit number at the start of every response that tells the client how its request went: 200 means it worked, 301 means the page has moved for good, 404 means nothing is at that address and 503 means the server cannot cope right now. The first digit gives the class, so even an unfamiliar code tells you whether to look at the request or at the server. Alongside it, the Content-Type header names the MIME type of the body, which decides whether a browser shows it, runs it or downloads it.

The five classes

RFC 9110, the current HTTP standard, defines most of the codes in use and groups them by their first digit:

Class Meaning Codes you will meet
1xx Informational An interim reply; the real response follows 100, 101, 103
2xx Success The request worked 200, 201, 204
3xx Redirection Look elsewhere, or use your cached copy 301, 302, 304, 307, 308
4xx Client error The request is wrong or not allowed 400, 401, 403, 404, 429
5xx Server error The server failed on a valid request 500, 502, 503, 504

Valid codes run from 100 to 599, and a client that meets an unknown code must treat it as the x00 of its class, so an unassigned 471 is handled like a 400. The reason phrase after the number is only a label, and HTTP/2 and HTTP/3 do not send it, which is how RFC 9110 could rename 413 to "Content Too Large" and 422 to "Unprocessable Content" without breaking anything.

2xx: the request worked

200 OK is the everyday success: for a GET, the body holds the page or the data. 201 Created says a POST or PUT made something new, and its Location header usually points to the new resource. 204 No Content reports success with an empty body, a common reply to a DELETE or to a save that needs no answer. An error page sent with a 200 is a soft 404, covered below.

3xx: redirects and 304

A redirect is a 3xx code plus a Location header naming the new address, which browsers follow automatically. The codes differ in permanence and in whether the method is kept:

Code Name Permanent Method kept
301 Moved Permanently Yes Not guaranteed
302 Found No Not guaranteed
303 See Other No No, the next request is a GET
307 Temporary Redirect No Yes
308 Permanent Redirect Yes Yes

For historical reasons RFC 9110 lets a client turn a POST into a GET after a 301 or 302, so 307 and 308 were added to rule that out. A 303 switches to GET on purpose, typically after a form submission, so reloading the result page does not resend the form. Browsers may also cache 301 and 308 responses, which RFC 9110 lists as cacheable by default, so test a new rule with 302 or 307 before making it permanent.

304 Not Modified is not a move. A browser holding a cached copy asks whether it has changed, sending the copy's ETag in If-None-Match or its date in If-Modified-Since, and a 304 with an empty body tells it to reuse the copy. How long a copy may be reused without asking is set by the Cache-Control header, which the Cache-Control Header Builder writes from plain time units.

Redirects, soft 404s and search engines

Google documents 301 and 308 as permanent redirects, a strong signal that the new URL should be the one shown in search, and 302, 303 and 307 as temporary, a weak signal that tends to leave the old URL indexed. Use a permanent code for real moves and send each old URL to its closest new equivalent in one hop; Google's crawlers follow at most 10 hops by default. The Redirect Map Generator turns an old-to-new list of URLs into permanent redirect rules for nginx, Apache, Netlify, Vercel or Cloudflare.

A soft 404 is a page that says "not found", or shows nothing useful, while returning 200, and Search Console flags it because the status claims there is content. Typical causes are a single-page app that answers every path with its shell page, and an Apache ErrorDocument pointed at a full URL, which makes Apache send a redirect so the client never receives the 404. The fix is a real 404 or 410 with a helpful page. In Apache, use a local path such as ErrorDocument 404 /404.html, which is how the .htaccess Generator writes it. In nginx, try_files $uri $uri/ =404;, the line the Nginx Config Generator uses for static sites, returns a true 404 for missing files.

404 or 410? Both say nothing is at the address, and 410 Gone adds that the removal is deliberate and likely permanent. Google's documentation says it handles every 4xx code except 429 the same way, dropping indexed URLs that return one.

Blocking a URL in robots.txt does not remove it either: Google stops crawling it, never sees its 404 or 410, and can still list the bare URL if other sites link to it. The robots.txt Generator is for steering crawlers away from areas such as admin paths.

4xx: problems with the request

Code Name What it usually means
400 Bad Request The request cannot be parsed, such as malformed JSON
404 Not Found Nothing at this address, or the server will not say
405 Method Not Allowed Wrong method; the Allow header lists the right ones
409 Conflict The request clashes with the current state, such as an outdated edit
410 Gone Removed on purpose, likely for good
413 Content Too Large The body is over the server's limit, often an upload
415 Unsupported Media Type The body's format is not accepted
422 Unprocessable Content Well-formed but invalid, such as a failed validation
429 Too Many Requests A rate limit was hit; Retry-After, if sent, says how long to wait

The line between 400 and 422 is syntax: a 400 means the server could not read the request, a 422 that it read it and found the content invalid. Google treats a 429 like a server error and slows its crawling. When uploads fail with 413 on nginx, the limit is client_max_body_size, 1 MB by default, which the Nginx Config Generator can set. The API Request Client shows the status and headers an API returns, if the API accepts cross-origin requests.

418 I'm a teapot comes from RFC 2324, a 1998 April Fools' protocol for coffee pots. The joke was deployed so widely that RFC 9110 reserves the number, so it cannot currently be reassigned.

401 vs 403

401 Unauthorized means the request lacks valid credentials, so "unauthenticated" would be the better name. The server must send a WWW-Authenticate header saying how to authenticate, and with Basic authentication that header is what makes a browser show its login dialog. Logging in can fix a 401.

403 Forbidden means the server understood the request and refuses it. If credentials were sent, RFC 9110 says they are insufficient and should not simply be sent again, so logging in again will not help. A server may also answer 404 instead of 403 to hide that a resource exists.

On your own server, a surprise 403 usually means the web server's user cannot read the file or enter a directory on its path (see Linux file permissions, explained), a folder has no index page and directory listing is off, or an IP rule blocks the visitor. The .htaccess Generator's IP blocking and its switch for disabling directory listing both produce 403s on purpose.

5xx: problems on the server

500 Internal Server Error is the catch-all for an unexpected failure, such as an unhandled exception or a broken configuration line (one invalid directive in an .htaccess file is enough). Servers normally keep the details out of the response, so check the error log.

502 Bad Gateway and 504 Gateway Timeout come from a proxy in front of the real server, such as nginx, a load balancer or a CDN. A 502 means the upstream server sent an invalid response or refused the connection, often because the app crashed or is not listening where the proxy expects; with the Nginx Config Generator's reverse-proxy mode, that is the address in proxy_pass, such as http://127.0.0.1:3000. A 504 means the upstream did not answer in time, and by default nginx gives up after 60 seconds without a reply.

503 Service Unavailable means the server is temporarily overloaded or down for maintenance, and a Retry-After header can say when to come back. It is the right code for planned downtime, because crawlers slow down and return later instead of indexing a maintenance page. Google does drop URLs that keep returning server errors, so keep the window short.

MIME types and Content-Type

A MIME type, or media type, is a two-part label for a kind of data, a top-level type and a subtype such as text/html or image/png, sometimes followed by parameters, as in text/html; charset=utf-8. IANA keeps the registry. A server declares the type of each response in the Content-Type header, and browsers act mainly on that header, not on the extension in the URL.

Extension MIME type
.html text/html
.css text/css
.js, .mjs text/javascript
.json application/json
.svg image/svg+xml
.png, .jpg, .webp image/png, image/jpeg, image/webp
.woff2 font/woff2
.pdf application/pdf
.zip application/zip
Any binary file application/octet-stream

RFC 9239 made text/javascript the standard type for JavaScript in 2022, and application/javascript still works but is obsolete. HTML forms submit as application/x-www-form-urlencoded, or as multipart/form-data when they carry files. A wrong type breaks things in predictable ways:

  • Scripts. Browsers refuse a module script that is not served with a JavaScript type, and with the X-Content-Type-Options: nosniff header they refuse ordinary scripts too. A missing bundle answered by an app's HTML fallback page is the classic case.
  • Stylesheets. A modern page ignores a stylesheet that is not served as text/css.
  • Downloads. A PDF sent as application/pdf opens in the browser's viewer, while the same file sent as application/octet-stream is downloaded. An HTML page sent as text/plain shows its source code.

Servers pick the type from the file extension, so when a newer format comes out wrong, add a mapping, such as AddType image/avif .avif in Apache or an entry in nginx's types block. The .htaccess Generator's security headers include nosniff, which tells browsers to trust the declared types.

Look up codes and types with the HTTP Reference

The HTTP Status & MIME Types reference has two tabs and one search box. The HTTP Status Codes tab lists 38 codes, from 100 Continue to 511 Network Authentication Required, each with its number, reason phrase and class, color-coded by class. Search matches any of the three: timeout finds 408 and 504, 50 finds every 50x code, and redirect lists all six 3xx codes. The MIME Types tab holds 44 entries, extension and type side by side, searchable by either, so png finds image/png. Each row has a copy button: a status row copies text such as 404 Not Found, and a MIME row copies just the type.

It lists names without explanations, and it covers the codes you are likely to meet rather than the whole IANA registry, so 412 Precondition Failed and 416 Range Not Satisfiable are missing. It uses the current RFC 9110 names, such as 413 Content Too Large and 422 Unprocessable Content. The list is built into the page, and your searches run in your browser.

Frequently asked questions

What is the difference between 301 and 302? A 301 says the move is permanent, so search engines switch to the new URL and browsers may cache the redirect. A 302 says it is temporary, so the old URL tends to stay in the index. Use 301 or 308 for real moves and 302 or 307 for short detours.

What is the difference between 404 and 410? Both mean nothing is at the address, and a 410 Gone adds that the removal is deliberate and probably permanent. Google says it treats all 4xx codes except 429 alike, so pick the one that describes the situation.

Should I use 301 or 308? For ordinary page moves either works, and Google treats them the same. A 308 also guarantees that a POST stays a POST, which matters for forms and API endpoints, while 301 is the older and more widely recognized code.

What is the difference between 401 and 403? A 401 means you have not proved who you are, and logging in may fix it. A 403 means the server refuses anyway, and logging in again will not help.

What is the difference between 502 and 504? Both come from a proxy or gateway in front of the real server. A 502 means the upstream sent an invalid response or refused the connection, often because the application is down, and a 504 means it did not respond in time.

What Content-Type should a JSON API use? application/json. RFC 8259 defines no charset parameter for it, because JSON exchanged between systems must be UTF-8, so adding charset=utf-8 changes nothing for a compliant client.

Keep going

Estados HTTP y tipos MIME

More guides

All Web & DevOps tools · All guides