/ โ† Redirect Fixes / 302 vs 301
In this guide
  1. What the two codes actually say
  2. 301, 302, 303, 307 and 308 side by side
  3. Where stray 302s come from
  4. How to check which code a URL returns
  5. The fix, step by step
  6. When a 302 is the right answer
  7. Platform notes
  8. Keeping 302s where they belong
  9. Questions and answers

What the two codes actually say

Both codes do the same thing for a visitor: the browser receives a Location header and loads the new address. The difference is the promise each one makes about the future.

Google has said that both 301 and 302 redirects pass ranking signals to the target, and that a 302 left in place for a long time may be treated much like a permanent one. So a stray 302 does not throw away the value of your old links. What it does is blur your intent. For a permanent move you want the new URL in search results, in reports and in every crawler's records as soon as possible, and a 302 asks them to keep an eye on the old one instead. Other search engines, SEO crawlers and link tools may be less forgiving than Google, and plenty of them simply report a 302 as a problem.

๐Ÿ’ก A quick test for any redirect: in a year's time, do you want people to find the old address or the new one in search results? If the new one, the redirect is permanent and should say so.

301, 302, 303, 307 and 308 side by side

Five redirect codes turn up in real reports. The newer ones exist because older browsers changed a form submission (POST) into an ordinary page request (GET) when following a 301 or 302.

CodePermanent?Method kept?Typical use
301YesNot guaranteedChanged page URLs, domain moves, HTTPS and host rules
308YesYesThe same as 301; the default permanent code in some frameworks and hosts
302NoNot guaranteedShort campaigns, maintenance, sending logged-out visitors to a login page
307NoYesTemporary moves of pages or API endpoints that receive form posts
303NoChanges to GETAfter a form is submitted, sending the visitor to a thank-you or results page

For search purposes, 308 is treated like 301 and 307 like 302. If the Redirect Checker shows a 308 on a permanent move, there is nothing to fix. A 303 after a form post is normal and should not be changed to a 301.

One trap: in Chrome's Network panel you may see 307 Internal Redirect when you type an http:// address. That is the browser upgrading the request itself because of HSTS, not your server sending a 307, so it will not appear in a server-side check.

Where stray 302s come from

Nearly every accidental 302 comes from a default. These are the ones worth knowing, because each needs an explicit permanent flag:

WhereWhat sends 302Permanent version
Apache mod_aliasRedirect /old /newRedirect 301 /old /new or Redirect permanent /old /new
Apache mod_rewrite[R] or [R,L][R=301,L]
nginx rewriterewrite ^/old$ /new redirect;return 301 /new; or the permanent flag
PHPheader('Location: /new'); on its ownheader('Location: /new', true, 301);
WordPress codewp_redirect() and wp_safe_redirect() without a statusPass 301 as the second argument
Express (Node.js)res.redirect('/new')res.redirect(301, '/new')
Djangoredirect(), HttpResponseRedirectredirect(url, permanent=True), HttpResponsePermanentRedirect
Laravelredirect('/new'), Route::redirect()Route::permanentRedirect() or a 301 status argument
Next.js configpermanent: false gives 307permanent: true gives 308

Hosting panels, redirect plugins and CDN rule builders usually offer a choice, but the pre-selected option varies and some forms remember whatever was picked last. Static hosts that read a _redirects file differ too: some default to 301 and some to 302, so always write the code on each line rather than relying on the default.

โš ๏ธ Login walls, language selectors and "choose your country" pages often redirect with 302 on purpose. If your homepage sends every visitor to /en-gb/ with a 302, think carefully before changing it: a 301 would tell search engines the homepage itself no longer exists.

How to check which code a URL returns

Browsers hide redirects, so use a tool that shows each hop. The Redirect Checker records the status code and Location header for every step, which makes a 302 in the middle of a chain easy to see. From a terminal, curl gives the same view:

curl -sI https://www.example.co.uk/spring-offer | grep -iE "^HTTP|^location"
HTTP/2 302
location: https://www.example.co.uk/offers/spring/

curl -sIL http://example.co.uk/old-page | grep -iE "^HTTP|^location"
HTTP/1.1 301 Moved Permanently
Location: https://example.co.uk/old-page
HTTP/2 302
location: https://example.co.uk/new-page
HTTP/2 200

The second example is common and easy to miss: the first hop is a proper 301 from the host rule, and the 302 is further down, added by whoever set up the page redirect. Check the whole chain, not just the first response.

In Search Console, the page indexing report and the URL Inspection tool show which URL Google has chosen as canonical. If a URL you redirected months ago is still the one Google shows, a 302 on that redirect is one of the first things to rule out, alongside canonical tags and internal links that still point at the old address.

For a whole site, run your list of old URLs through the checker in batches, or crawl the site with a desktop crawler, and filter the results by status code. Export the 302s into a sheet with columns for the old URL, the target, the layer that sent it and whether the move is permanent.

The fix, step by step

Step 1

List every redirect that answers 302

Run the Redirect Checker on your homepage, top landing pages and a list of old URLs from past site versions, old sitemaps and backlink reports. Note every hop that returns 302 or 307, including ones buried in the middle of a chain behind a correct 301. Put each one in a sheet with the requested URL, the Location it points to and the date you found it, so nothing gets lost while you work through them.

Step 2

Sort permanent moves from genuine temporary ones

Go through the sheet and mark each redirect as permanent or temporary. Renamed pages, merged articles, deleted products with a close replacement, HTTPS rules and host rules are permanent. A seasonal campaign, a maintenance page, a login redirect for logged-out visitors, a test, or a language or country picker may be genuinely temporary and should keep its 302 or 307. When in doubt, ask whether the old address will ever serve content again.

Step 3

Trace each 302 to the layer that sends it

Look at the response headers for clues. A server or cf-ray header can show a CDN answered, an x-redirect-by header is added by WordPress and some plugins, and a response that arrives very quickly with no application cookies often came from the edge. Then search each likely place in turn: CDN rules, hosting panel redirects, .htaccess or server config, the CMS redirect manager and application code.

Step 4

Change the status code at the source

Edit the rule where it lives rather than adding a new one on top. In Apache write Redirect 301 or [R=301,L], in nginx use return 301, in PHP pass 301 as the third argument to header(), and in frameworks use the permanent option. In plugin or panel forms, open the existing entry and change its type. Keep a note of each change so it can be reversed if a move turns out to be temporary.

Step 5

Point the redirect straight at the final URL

While you are editing each rule, check where its target goes. If the target itself redirects, change the rule to point at the final address with a 200 response, including the right protocol, host and trailing slash. A permanent redirect into a chain of other redirects still works, but it wastes a round trip on every request and makes the next change harder. One rule, one hop, one final URL is the goal for every row.

Step 6

Confirm the new code and update your own links

Purge the CDN and any page cache, then re-run the Redirect Checker and confirm each changed row now shows 301 or 308 followed by a 200. Test in a private window or with curl, because your own browser may hold old responses. Finally, update internal links, canonical tags, the XML sitemap, email templates and ad destinations so they use the new URL directly and stop relying on the redirect.

When a 302 is the right answer

Switching everything to 301 is its own mistake, because browsers can hold on to a 301 for a long time and you cannot recall it from a visitor's machine. Keep a temporary code for these cases:

What matters for these is that they really are temporary. A "temporary" redirect from a campaign that ended two years ago is a permanent redirect in disguise: either change it to a 301 or, if the old page has nothing to replace it, let the old address return a 404 or 410.

Platform notes

WordPress

Redirect plugins and SEO plugins with redirect managers let you pick the type per entry. Check the default in each plugin's settings before a large import, because a CSV imported without a code column may take the default. Code in themes and small plugins often calls wp_redirect() without a status, which gives 302. The WordPress redirects guide covers finding which plugin answered.

Shopify and hosted platforms

Shopify's URL redirects feature creates permanent redirects, so a 302 on a Shopify store usually comes from an app, a theme script or a rule at a CDN in front of the store. Other hosted builders vary; if the platform gives no choice of code and sends 302 for moved pages, raise it with the platform's support and record the limitation.

Cloudflare and other CDNs

Edge redirect rules ask for a status code when you create them. Old rules made in legacy features may carry whatever code was chosen years ago, so list them all rather than assuming. The Cloudflare guide covers where each kind of rule lives.

Custom code and APIs

Search the codebase for the redirect helper your framework uses and check every call has an explicit status. A linting rule or code review checklist item that requires the status argument stops the default from creeping back in.

Keeping 302s where they belong

Questions and answers

1. Does a 302 redirect hurt SEO?

Not in the way it is often described. Google has said that 302 redirects pass signals to the target page, just as 301s do, and that a long-lasting 302 may be treated as permanent. The real cost is ambiguity: the old URL may stay in results for longer, reports stay cluttered, and other search engines and tools may handle it less generously. For a move that will not be reversed, a 301 states your intent clearly, which is why it is still the right choice.

2. How do I change a 302 redirect to a 301?

Find the layer that sends the 302 and change the code there. In Apache use Redirect 301 or add R=301 to the rewrite flags; in nginx use return 301; in PHP pass 301 as the third argument of header(); in WordPress code pass 301 to wp_redirect(); in frameworks use the permanent option. In a plugin, hosting panel or CDN rule, edit the existing entry and change its type. Then purge caches and re-check the URL to confirm the new code.

3. Why does my redirect show 302 when I set it up as permanent?

Usually because a different layer is answering first. A CDN rule, hosting panel redirect or plugin may catch the request before your intended rule runs, or your 301 may be the first hop of a chain whose second hop is a 302. Cached responses can also mislead you. Check the full chain with the Redirect Checker or curl, read the response headers for signs of which system replied, and test in a private window after purging caches.

4. Is a 308 redirect the same as a 301 for SEO?

For search purposes, yes. Google treats 308 as a permanent redirect in the same way as a 301. The difference is technical: a 308 guarantees the browser repeats the same request method, so a form post stays a post, while a 301 may be turned into an ordinary GET by the browser. Some frameworks and hosts use 308 by default for permanent redirects, and there is no need to change those to 301 unless an old client cannot handle 308.

5. How long can I leave a 302 in place?

As long as the move is genuinely temporary. There is no fixed limit, but a 302 that has been in place for months with no plan to reverse it is really a permanent redirect with the wrong label, and Google may start treating it as one anyway. Give every temporary redirect an end date in your records. When that date arrives, either remove the redirect because the original page is back, or change it to a 301.

6. Should I use a 302 or a 503 during site maintenance?

For a short outage of the whole site, a 503 Service Unavailable with a Retry-After header on the original URLs is usually the better signal, because it tells crawlers to come back later without suggesting any page has moved. A 302 to a maintenance page is acceptable for a single section for a short time. Avoid a 301 for maintenance, because browsers may remember it and keep sending visitors to the holding page after the site is back.

7. Will changing a 302 to a 301 cause any problems?

Usually not, as long as the move really is permanent. The risk is that browsers can cache a 301 for a long time, so if you later want the old URL back, some returning visitors will keep being sent to the new one until their cache clears. Before switching, confirm the old address will never serve its own content again. Also make sure the target returns a 200, so you are not making a chain or loop permanent.

See the status code on every hop

The Redirect Checker follows each URL through its full chain, recording every status code, Location header and hop time, and flags 302s that should be 301s alongside long chains, loops, HTTPS gaps and mixed content.

Open Redirect Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Redirect Fixes  ·  Multi-Hop Redirect Chains  ·  Migration Redirects  ·  Redirect Checker Guide  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.