sfw/fix
302 medium

302 Redirect Used Instead of 301

A 302 (temporary) on a permanently moved page tells search engines the old URL will return, so ranking signals never consolidate.

What you see

curl -I https://example.com/old-page
HTTP/1.1 302 Found
Location: https://example.com/new-page

What’s actually happening

The page redirects and visitors land in the right place, so it looks fine. But `curl -I` shows a 302 (or 307) where a 301 belongs. To a search engine a 302 means "this move is temporary, keep the original URL around," so Google keeps the old URL indexed, is slow to transfer ranking to the new one, and may show the old URL in results long after the move. For a permanent move that's the wrong signal — you're sitting on a temporary redirect for something that's never coming back.

Common causes

  • A plugin or redirect tool that defaults to 302 (many do — the WordPress default for some redirect managers and several framework helpers emit 302 unless told otherwise).
  • A framework redirect helper that's temporary by default — e.g. `redirect()` returning 302; you need the explicit permanent variant (`RedirectPermanent` / `301`).
  • A server rule written with the wrong flag (`Redirect` vs `Redirect 301` in Apache, or `redirect` vs `permanent` in Nginx).
  • A 307 issued by an HSTS upgrade or a proxy, mistaken for the intended permanent redirect.
  • Someone set it 302 deliberately for a short test or A/B and never switched it back.

How to fix it

  1. Confirm the status code`curl -I https://example.com/old-page` and read the status line. 302/307 = temporary; 301/308 = permanent. Don't trust the browser — it sends you to the right page either way and hides the code.
  2. Change it to a 301 at the sourceIn Apache use `Redirect 301 /old /new` or `[R=301,L]`; in Nginx use `return 301 https://example.com/new;`; in a redirect plugin pick "301 Permanent" from the type dropdown; in code call the permanent-redirect helper. Re-run curl to confirm it now says 301.
  3. Use 302 only when the move really is temporaryA genuine temporary case — a maintenance page, a short promo URL, geolocation routing — should stay 302. The fix isn't "always 301," it's matching the code to whether the original URL is coming back.
  4. Recrawl so signals consolidateAfter switching to 301, request the old URL via URL Inspection and let Google recrawl. Ranking and link equity migrate to the new URL over the following crawls, and the old URL drops from the index.

Stop it recurring

Default to 301 for permanent moves and audit redirect rules with `curl -I` after setup, since plugins and framework helpers quietly emit 302 unless you specify permanent.

Related errors