Redirects and status codes: 301, 302, 404 and 503
What 301, 302, 307, 308, 404, 410 and 503 mean, when to use each, why redirects cost speed, how to avoid chains and loops, and how to check your site.
In this guide
How a redirect works
MDN explains the principle. A redirect is triggered by a server sending a special response whose status code starts with 3 and which carries a Location header holding the new address. The browser immediately loads the new address. Besides the small performance cost of the extra round trip, users rarely notice.
GET /old-page → 301 Moved Permanently, Location: /new-page
GET /new-page → 200 OKRedirects serve a few jobs. Temporary redirects can cover maintenance or downtime. Permanent redirects preserve existing links and bookmarks after addresses change. Common cases listed by MDN are making example.com and www.example.com reach the same place, moving to a new domain, and forcing https.
Permanent and temporary redirects
| Code | Name | Meaning | What happens to a POST |
|---|---|---|---|
| 301 | Moved Permanently | The old address should no longer be used. Crawlers and other tools update their records. | May be changed to GET |
| 308 | Permanent Redirect | Same meaning as 301 | Method and body kept |
| 302 | Found | Temporary. Crawlers do not remember the new address. | May be changed to GET |
| 307 | Temporary Redirect | Same meaning as 302 | Method and body kept |
| 303 | See Other | Used after a form submission, so that reloading the result page does not repeat the action | Changed to GET |
MDN says permanent redirects imply the original address should no longer be used, so search engine robots and other crawlers update the original address. Temporary ones are the opposite: crawlers do not remember the new temporary address. That is why the choice between 301 and 302 matters. A 302 used for a permanent move can leave the old address in place.
The 308 and 307 codes exist to remove an ambiguity. The original specification did not intend 301 and 302 to allow a change of request method, but some browsers do change it. For ordinary pages visited with GET, 301 and 302 are fine.
The other codes you will meet
| Code | Meaning | Use |
|---|---|---|
| 200 | OK | A normal page |
| 304 | Not Modified | The cached copy is still good. This is a caching response, not a move. See HTTP caching headers |
| 404 | Not Found | The server cannot find it. MDN notes it does not say whether this is temporary or permanent |
| 410 | Gone | The resource is no longer available and this is likely permanent. Clients should not repeat the request, and owners should remove or replace links to it |
| 503 | Service Unavailable | The server is not ready: down for maintenance or overloaded. Should be temporary |
| 429 | Too Many Requests | The right answer when one client is rate-limited |
MDN's advice on 404 and 410: if a resource is permanently removed, servers should send 410 instead of 404. If you do not know whether it is temporary or permanent, use 404. Too many broken links, internal and external, lead to a poor experience, so keep them to a minimum.
For maintenance, MDN says a 503 should be used for temporary conditions, with a Retry-After header holding the estimated time of recovery if possible, and with a user-friendly page. A 503 tells crawlers that the problem is temporary. A 200 with a message "we are down" does not.
What search engines make of them
Lighthouse's documentation says that a search engine that meets a 4xx or 5xx while crawling may not index the page properly. Its audit flags pages that return an unsuccessful status. Its advice is that the server should return a 200-series code for all valid addresses, and a 300-series code for something that has moved. A page that shows an error, such as your 404 page, should not be in search results.
A trap for single-page apps: a page that does not exist can still be sent with a 200 and shown as an error by the script. The Lighthouse documentation points to a tutorial on fixing these sneaky 404s. A missing page should return a real 404 status.
Why redirects cost speed
MDN is plain about it: as performance is impacted with every redirect, their use should be kept to a minimum. The Lighthouse documentation says the extra trip across the network can delay the loading of the resource by hundreds of milliseconds, and that avoiding redirects in resources required to render the page matters most.
In Lighthouse 13.5, the redirect check is part of the Document request latency insight, and it fails the page when it was redirected. See server response time. The redirect time also counts in time to first byte.
The usual sources:
- A chain of redirects.
http://example.comtohttps://example.comtohttps://www.example.comtohttps://www.example.com/with a trailing slash. Each hop is a round trip. - Internal links to old addresses. MDN says that when you can avoid a redirect by correcting internal links, fix the links.
- Redirects to another host. They need a new connection, with a name lookup and a secure handshake. See DNS, TLS and connections.
- Redirects on resources, such as images, scripts and styles, that the page needs.
- Separate mobile addresses. The Lighthouse advice is to use responsive design instead of redirecting phones to a mobile version.
The fix is the same each time: link directly to the final address, and if a redirect is unavoidable, make it a single hop. Use https, the version of your domain you chose, and the trailing slash if your site uses one.
Chains and loops
A chain is a redirect that leads to another redirect. Combine the rules so each old address goes straight to the final one.
A loop is worse. MDN explains that a redirect loop happens when additional redirections keep following the one already followed, so no page is ever found. A server that detects it may send a 500 error. Otherwise the browser gives up and shows a message such as "This Webpage has a redirect loop". If you see a 500 error soon after changing a server configuration, a loop is a likely cause.
Redirects in HTML and JavaScript
HTTP redirects are the best way. When you cannot control the server, there are two others. A meta element with http-equiv="Refresh" redirects after the page loads, and MDN says to set its delay to 0 for accessibility. A script can set window.location. MDN gives the order: HTTP redirects run first, because they happen before a page is even sent. JavaScript redirects run next. The meta redirect runs after the page is completely loaded, so it comes later than scripts that run while loading.
MDN's advice is to use HTTP redirects where possible and avoid the meta kind. If someone changes the HTTP rule and forgets the HTML one, they can disagree, which could cause an infinite loop.
How to set a redirect
MDN gives examples for common servers.
Apache, in the server configuration or an .htaccess file:
# permanent redirect from one host to another
Redirect permanent / https://www.example.com
# the same, with the code written out
Redirect 301 / https://www.example.comRedirect sends a 302 by default, so add permanent or 301 for a permanent move.
Nginx, in a server block for the host to redirect:
server {
listen 80;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}IIS uses the httpRedirect element. On a content management system, redirects are often handled by a plugin, a setting or the hosting control panel. Use one place for them, so rules do not conflict.
Common situations
| Situation | Do this |
|---|---|
Two versions of your domain (www and bare) | Pick one. 301 the other to it. Use the chosen one in all links |
http and https | 301 from http to https, in one hop to the final host |
| You moved a page | 301 from the old address to the closest matching new page |
| You deleted a page for good, with no replacement | 410, or 404 if unsure |
| The site is down for maintenance | 503 with Retry-After |
| You changed domains | 301 every old address to its exact new address, not all to the home page |
| A form was submitted | 303 to a results page, so reload does not resubmit |
How to check
- Follow the chain with a tool. From a terminal,
curl -sIL https://example.com/old-pageprints each response's headers, and the status andLocationlines show every hop. Count the hops. - Use the Network panel. Tick Preserve log, load the address, and look at the status column and the Initiator. The filter
status-code:301finds redirects. See the Network panel. - Run Lighthouse. The Document request latency insight shows redirects, and the SEO audit flags error statuses.
- Test your 404 page by opening an address that does not exist, and confirm that the status is 404, not 200.
- Test a few old addresses after any move.
Mistakes to avoid
- A 302 for a permanent move.
- Chains.
httptohttpstowwwto a slash is three hops where one will do. - Sending every old address to the home page. Visitors and crawlers who expected a specific page land somewhere unrelated.
- A 200 on an error page.
- Redirect loops after a server change.
- Redirecting images, scripts or styles the page needs.
- Two redirect systems (plugin plus server rules) that fight.
Check your own page
Run the free audit and look at Document request latency for a redirect. Then run curl -sIL on your home page as you type it in four ways: with and without www, over http and over https. Each should reach the same final address in one hop at most.
Sources
- Redirections in HTTP on MDN, with the pages for 301, 302, 307, 308, 404, 410 and 503.
- Page has unsuccessful HTTP status code and Avoid multiple page redirects in the Lighthouse documentation.
- The Lighthouse 13.5 source for the Document request latency insight, as used in the server response time guide.
Start here
Free website audit
Live Google data for any public page: mobile and desktop.
Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it
Rather have this done for you? Technical SEO · Book a call