301 vs 302 Redirect: When to Use Each
The most common source of confusion in HTTP redirects. This guide explains when permanent and temporary redirects matter, with practical examples for web developers.
Why Redirects Matter
HTTP redirects are one of the most fundamental mechanisms on the web. Every time a URL changes, a domain migrates, a page moves to a new location, or a user needs to be sent somewhere else after an action, a redirect is involved. Yet despite their ubiquity, redirects are frequently misconfigured because developers conflate two very different behaviors: permanent and temporary redirection.
The consequences of choosing the wrong redirect type range from minor inconveniences to serious SEO damage. A temporary redirect where a permanent one was needed means search engines keep indexing the old URL, splitting your page authority between two addresses. A permanent redirect where a temporary one was needed can cause browsers to cache the redirect so aggressively that users cannot reach the original URL even after the redirect is removed.
This guide explains the practical differences between 301 and 302 redirects, introduces their modern counterparts (307 and 308), and provides clear decision criteria for choosing the right type. Use the HTTP Status Code Reference tool to look up any redirect code and see code snippets for your framework.
301 Moved Permanently
A 301 Moved Permanently response tells the client that the requested resource has been permanently moved to a new URL. The key word here is permanently. This has two critical implications:
- Browser caching: Browsers cache 301 redirects aggressively. Once a browser encounters a 301, it may never request the original URL again, instead going directly to the new location on subsequent visits. The cache duration varies by browser but can persist for months.
- Search engine behavior: Search engines interpret a 301 as a signal to transfer the ranking value (often called "link equity" or "link juice") from the old URL to the new URL. Over time, the old URL is removed from the search index and replaced by the new one.
When to Use 301
- You have permanently changed a URL structure (e.g.,
/blog/my-postto/articles/my-post) - You are migrating an entire domain (e.g.,
oldsite.comtonewsite.com) - You have consolidated duplicate content (e.g.,
www.example.comandexample.comto a single canonical) - A product or page has been permanently replaced by another
- You are enforcing HTTPS by redirecting all HTTP traffic
301 Example
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page
Cache-Control: public, max-age=31536000
# Nginx configuration
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
# Next.js next.config.js
async redirects() {
return [
{
source: '/old-path',
destination: '/new-path',
permanent: true, // This generates a 308 by default in Next.js
},
];
}302 Found (Temporary Redirect)
A 302 Found response tells the client that the resource is temporarily located at a different URL. The client should continue using the original URL for future requests because the redirect could change or be removed at any time.
- Browser caching: Browsers do not cache 302 redirects by default (though they can if explicit caching headers are set). Each visit to the original URL triggers a new request to the server, which checks whether the redirect is still active.
- Search engine behavior: Search engines keep the original URL in their index and do not transfer ranking value to the temporary destination. This is the correct behavior when you intend to bring the original URL back.
When to Use 302
- A/B testing where you are temporarily routing users to a variant page
- Maintenance mode: temporarily redirecting to a maintenance page while the site is updated
- Geo-based routing: sending users to a region-specific version that may change
- Login flows: redirecting unauthenticated users to a login page, then back to the original URL after authentication
- Temporary promotions or seasonal content redirects
302 Example
HTTP/1.1 302 Found
Location: https://example.com/maintenance
# Express.js
app.get('/dashboard', (req, res) => {
if (maintenanceMode) {
return res.redirect(302, '/maintenance');
}
res.render('dashboard');
});
# Apache .htaccess
RewriteEngine On
RewriteRule ^old-page$ /temp-page [R=302,L]The Historical Problem: Method Changing
There is a well-known historical issue with both 301 and 302 redirects. The HTTP specification originally stated that the request method should be preserved during a redirect. If a client sends a POST request and receives a 301 or 302, it should send another POST to the new URL with the same body.
In practice, almost every browser changed POST requests to GET requests when following a 301 or 302 redirect. This behavior was so universal that it became the de facto standard, even though it contradicted the specification. This caused real problems for applications that relied on POST data being preserved through redirects, such as payment processing flows and form submissions to third-party services.
To resolve this ambiguity, RFC 7231 (later updated by RFC 9110) introduced two new redirect codes that explicitly define whether the method can change:
307 Temporary Redirect
The 307 Temporary Redirect is semantically identical to 302, with one crucial guarantee: the HTTP method and request body must not change during the redirect. If the client sends a POST with a JSON body and receives a 307, it must send the same POST with the same body to the new URL.
Use 307 instead of 302 when you need to preserve the request method. This is particularly important for API endpoints that handle POST, PUT, or DELETE requests.
308 Permanent Redirect
The 308 Permanent Redirect is the permanent counterpart to 307. It functions like a 301 (permanent move, SEO transfer, browser caching) but guarantees that the request method will not change. Use 308 when you permanently move an API endpoint that accepts non-GET methods.
Note that Next.js uses 308 instead of 301 as the default for permanent redirects in its configuration, specifically because 308 prevents the method-changing behavior.
Decision Matrix
Use this decision matrix to choose the correct redirect code:
| Scenario | Permanent? | Preserve Method? | Use |
|---|---|---|---|
| Page moved, GET only | Yes | Not critical | 301 |
| API endpoint moved permanently | Yes | Yes | 308 |
| Temporary maintenance page | No | Not critical | 302 |
| Temporary API reroute | No | Yes | 307 |
| HTTP to HTTPS upgrade | Yes | Yes | 308 |
| A/B test routing | No | Not critical | 302 |
| Domain migration | Yes | Not critical | 301 |
| Login redirect | No | Not critical | 302 |
SEO Implications
The SEO difference between 301 and 302 is significant. Google and other search engines treat these codes differently:
- 301/308 (permanent): Search engines transfer most of the original page's ranking signals to the new URL. After a few weeks, the old URL is typically dropped from the index entirely. Google has confirmed that 301 redirects pass full link equity.
- 302/307 (temporary): Search engines keep the original URL in the index and do not transfer ranking signals. If a 302 remains in place for a very long time, Google may eventually treat it as a 301, but this behavior is not guaranteed and relies on Google's heuristics rather than explicit intent.
The most common SEO mistake is using a 302 when a 301 is appropriate. This happens frequently with URL migrations, CMS platform changes, and domain consolidations. If you intend for the old URL to go away permanently, always use a 301 or 308.
Common Mistakes to Avoid
- Redirect chains: A redirects to B, which redirects to C, which redirects to D. Each hop adds latency and reduces the amount of link equity passed. Keep redirect chains to a maximum of one hop (ideally zero: redirect directly from A to D).
- Redirect loops: A redirects to B, and B redirects back to A. Browsers detect this and show an error, but it still wastes server resources and frustrates users.
- Using 302 for permanent moves: If the move is permanent, use 301. A 302 tells search engines "this is temporary, keep the old URL indexed," which defeats the purpose of the migration.
- Not setting the Location header: A redirect without a
Locationheader is technically invalid and causes unpredictable behavior across different clients. - Forgetting to update internal links: After adding a redirect, update all internal links to point directly to the new URL. Relying on the redirect for internal navigation adds unnecessary server round trips.
Testing Redirects
Always verify your redirects are working correctly. Use curl -I (capital I for headers only) to check the response code and Location header:
# Check redirect type and destination
curl -I https://example.com/old-page
# Follow all redirects and show each hop
curl -ILv https://example.com/old-page
# Check for redirect chains
curl -sIL -o /dev/null -w "%{url_effective}\n" https://example.com/old-pageYou can also check HTTP response headers and redirects using our Domain Intelligence tool, which fetches and displays all response headers including redirect chains for any URL.
Further Reading
- RFC 9110 — HTTP Semantics (Redirections)
The IETF specification defining HTTP redirect status codes.
- MDN HTTP redirections
Practical guide to HTTP redirects, types, and browser behavior.
- Google Search Central — Redirects
Google's guidance on how redirects affect search ranking and indexing.