Skip to content
TurboIndex

301 vs 302 Redirects: What Each One Means for SEO

When to use 301, 302, 307 and 308 redirects, how Google treats permanent and temporary redirects, config examples for nginx and Apache, and mistakes to avoid.

September 3, 20267 min read

A 301 says a URL has moved permanently, and a 302 says it has moved for now. Google follows both. The difference is in which URL it keeps: a permanent redirect (301 or 308) is a strong signal that the target should replace the old URL in the index, while a temporary redirect (302, 303 or 307) is a weak signal, so Google tends to keep showing the original. Use the one that matches your intent, and you rarely need to think about it again.

The four codes you will actually use

Code Meaning Request method preserved? Google's treatment
301 Moved Permanently Permanent Not guaranteed (clients may switch POST to GET) Strong canonical signal for the target
308 Permanent Redirect Permanent Yes Same as 301
302 Found Temporary Not guaranteed Weak canonical signal for the target
307 Temporary Redirect Temporary Yes Same as 302

For ordinary page URLs requested with GET, 301 and 308 are interchangeable for SEO, and so are 302 and 307. The method-preserving variants matter for APIs and form submissions.

One thing that confuses people when testing HTTPS: Chrome shows a "307 Internal Redirect" for hosts with HSTS enabled. The browser generates that itself without contacting the server. Googlebot never sees it. Test with a command line client to see what the server really returns:

curl -sI http://example.com/old-page | head -n 5

When to use a permanent redirect

  • Changing a URL slug or restructuring folders.
  • Moving to a new domain.
  • HTTP to HTTPS, and choosing between www and non-www.
  • Merging two pages about the same subject into one.
  • Replacing a discontinued product with its direct successor.
  • Normalising trailing slashes or letter case.

In all of these, the old URL is never coming back, and you want links, bookmarks and search signals to end up on the new one.

When to use a temporary redirect

  • A product page sent to its category while the item is briefly unavailable, where you intend to restore the page.
  • A seasonal landing page that points elsewhere out of season.
  • A/B tests that send part of the traffic to a variant URL. Google's testing guidance specifically recommends 302 for this.
  • Redirects to a login page, or from a login to the requested page.
  • Redirecting by country or language preference, if you must do it at all. Be careful here: Googlebot mostly crawls from US IP addresses and does not send an Accept-Language header, so automatic geo redirects can hide your other language versions from it. See the hreflang guide.

If a 302 stays in place for a long time, Google may decide the move is effectively permanent and index the target. That is a safety net, not a plan. If the move is permanent, say so.

What happens in Google after a 301

  1. Googlebot requests the old URL, receives the 301 and queues the target.
  2. The target is crawled. If it is a good match for the old content, Google starts treating it as the canonical of the pair.
  3. Over the following weeks the new URL replaces the old one in results. The old URL appears in Search Console under Page with redirect, which is expected.
  4. Links pointing to the old URL count towards the new one.

A redirect is one canonical signal among several. If your sitemap, internal links and canonical tags still reference the old URL, you are contradicting yourself and the switch takes longer. After any redirect project, update those three to the final URLs. Background in the canonical tags guide.

Configuration examples

nginx

# Single URL
location = /old-page {
    return 301 /new-page;
}

# Whole folder, keeping the rest of the path
location ^~ /blog/ {
    rewrite ^/blog/(.*)$ /articles/$1 permanent;
}

# HTTP to HTTPS and non-www to www, in one hop
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}
server {
    listen 443 ssl;
    server_name example.com;
    return 301 https://www.example.com$request_uri;
}

Apache (.htaccess)

# Single URL
Redirect 301 /old-page /new-page

# Whole folder
RedirectMatch 301 ^/blog/(.*)$ /articles/$1

# HTTP to HTTPS and non-www to www, in one hop
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [L,R=301]

Application level (Next.js as an example)

// next.config.js
module.exports = {
  async redirects() {
    return [
      { source: "/old-page", destination: "/new-page", permanent: true },
    ];
  },
};

In Next.js, permanent: true sends a 308 and false sends a 307. Both are handled by Google like 301 and 302.

If you have a long mapping of old to new URLs, the Redirect Rule Generator turns it into rules for Apache, nginx, Cloudflare or Netlify.

Redirect chains and loops

A chain is a redirect that leads to another redirect:

http://example.com/page
  -> 301 https://example.com/page
  -> 301 https://www.example.com/page
  -> 301 https://www.example.com/page/

Googlebot follows up to 10 hops, so a three hop chain still resolves. It is still worth fixing: every hop adds latency for users, costs an extra crawl request, and adds one more place for a misconfiguration to turn the chain into a loop. Chains grow quietly over the years, when each migration adds a layer on top of the previous one. After a migration, rewrite old rules so they point straight at the current destination.

A loop (A to B, B to A) or a chain beyond the limit shows up in Search Console as "Redirect error". Browsers show "too many redirects". Frequent causes are conflicting rules between the CDN and the origin (the CDN forces HTTPS while the origin forces HTTP behind a proxy that does not pass X-Forwarded-Proto), and trailing slash rules in both the server and the application that disagree.

Trace the full path of any URL with the Redirect Checker, which lists each hop and its status code.

Client-side redirects

When you cannot touch the server config, there are two fallbacks.

Meta refresh:

<meta http-equiv="refresh" content="0; url=https://www.example.com/new-page">

Google treats an instant meta refresh (0 seconds) as a permanent redirect and a delayed one as temporary.

JavaScript:

<script>window.location.replace("https://www.example.com/new-page");</script>

Google only sees a JavaScript redirect after it has rendered the page, which can lag behind crawling, and other crawlers may not see it at all. Google's documentation ranks server-side redirects first, then meta refresh, and JavaScript only if nothing else is possible. If you cannot redirect at all, a canonical tag on the old page pointing to the new one is a weaker alternative.

Mistakes that cost rankings

Redirecting everything to the homepage. After a redesign or when products are retired, sending all old URLs to / is tempting. Google typically treats redirects to an irrelevant page as soft 404s, so nothing is preserved. Map each old URL to its nearest equivalent, and let the URLs without one return 404 or 410.

Using 302 because it was the default. Many frameworks, plugins and hosting panels default to temporary redirects. Check the actual status code after setting one up.

Leaving internal links on old URLs. The redirect catches them, but every click and every crawl goes through an unnecessary hop, and your own site keeps voting for the old URL.

Listing redirected URLs in the sitemap. The sitemap should only contain final, 200 status URLs. See the XML sitemap guide.

Blocking the old URLs in robots.txt. If Googlebot may not fetch the old URL, it never sees the redirect, and the old URL can stay indexed.

Removing redirects too early. Google advises keeping them for at least a year. Links on other sites will point at the old URLs for much longer than that.

Redirecting to a different URL than the canonical tag says. Old URL redirects to /new-page/, whose canonical says /new-page. Now Google has three candidates. Make the redirect target the exact canonical URL.

Dropping query strings or paths by accident. A rule such as return 301 https://www.example.com; sends every deep URL to the homepage. Include $request_uri (nginx) or %{REQUEST_URI} (Apache) when the path should be kept.

Testing a redirect project

  1. Before launch, export the full list of old URLs from your sitemap, analytics, Search Console and a crawl.
  2. After launch, request every old URL and record the status, the number of hops and the final URL. For small batches, the Bulk HTTP Status Checker does this.
  3. Confirm each final URL returns 200, is indexable and has a self-referencing canonical.
  4. Watch the Page indexing report: "Page with redirect" should grow for old URLs, while "Not found (404)" and "Redirect error" should not.
  5. For a domain move, also use the Change of Address tool in Search Console.

A full move has more parts than redirects alone. The site migration indexing checklist covers the rest.

Frequently asked questions

Do 301 redirects lose PageRank?
Google has stated that 30x redirects no longer lose PageRank. What you can lose is relevance: if the target page covers a different topic from the old one, the old page's rankings will not carry over, and Google may treat an irrelevant redirect as a soft 404.
Will a 302 redirect hurt my SEO?
Not when the move really is temporary. With a 302, Google tends to keep the original URL in its index. If you use a 302 for a permanent move, consolidation on the new URL is slower and less predictable, although Google may eventually treat a long-standing 302 as permanent.
How long should I keep a 301 redirect in place?
Google recommends keeping redirects for at least a year, so that it has time to transfer all signals. For users and for links on other websites, keeping them indefinitely is better whenever you can.
Are JavaScript and meta refresh redirects okay?
Google can follow both, but server-side redirects are the most reliable. An instant meta refresh is treated as permanent and a delayed one as temporary. JavaScript redirects only work after the page has been rendered, so use them only when you cannot configure the server.

Keep reading