HTTP 302 Found is a temporary redirect — the wrong choice for permanent moves and a common source of lost SEO equity if used incorrectly.
HTTP 302 Found tells clients: the resource you asked for is temporarily at a different URL — please request the new URL this time, but keep using the old URL for future requests. It is one of three commonly used redirect codes (301, 302, 308) and the one most often misused. The original HTTP/1.0 spec called it 'Moved Temporarily'; HTTP/1.1 renamed it to 'Found' and clarified the semantics. The key word is TEMPORARY. A 302 says: do not update bookmarks, do not pass link equity to the new URL, do not change your indexed entry — just follow the redirect this once. Compare to 301 Moved Permanently, which says: update everything, transfer all the SEO equity, treat the new URL as canonical. The difference between 301 and 302 is the difference between forwarding mail for a vacation versus moving house permanently — and Google treats them accordingly.
Most accidental 302s come from frameworks that default to 302 when developers expected 301. Express.js's `res.redirect(url)` defaults to 302. Flask's `redirect(url)` defaults to 302. Laravel's `redirect()` defaults to 302. Django's `HttpResponseRedirect` is 302. Rails's `redirect_to` is 302. Unless you explicitly pass a status code, your framework is silently issuing 302s for everything — including permanent URL migrations where you needed a 301. The second-most common cause is authentication middleware: 'redirect to login if not authenticated' loops are almost always 302 (correctly), but those redirects sometimes leak into SEO crawl data and confuse audit tools. Third-most common: A/B testing platforms (Optimizely, VWO, Google Optimize) that 302-redirect a percentage of traffic to a variant. Fourth: geo-redirect logic that 302s users to a country-specific page based on IP. Each of these is technically correct usage of 302, but the cumulative effect is a crawl report full of 302s that mask real issues.
Step 1: Crawl your site with Screaming Frog, Sitebulb, or any equivalent and filter for 302 responses. Step 2: For each 302, ask: is this redirect temporary, or have I been routing the same URL to the same target for more than 90 days? If it is permanent, change to 301. Step 3: Check your framework's default. In Express, change `res.redirect(url)` to `res.redirect(301, url)`. In Flask, change to `redirect(url, code=301)`. In Laravel, change to `redirect($url, 301)`. Step 4: For auth-gated routes, leave the 302 — that is the correct semantic. Step 5: For A/B test or geo-redirect logic, consider whether server-side redirect is even the right tool — for many cases, client-side rendering of variants is faster and avoids the SEO ambiguity entirely. Step 6: After cleanup, re-crawl and confirm only legitimate temporary redirects remain. Submit the corrected sitemap to Google Search Console and use the URL Inspection tool to confirm the canonical attribution moved correctly.
Here is a working Nginx snippet that addresses the most common 302 scenarios. Drop this into your server block and reload with `sudo nginx -t && sudo systemctl reload nginx`.
# Wrong (returns 302): # location /old-page { return 302 /new-page; }
# Right — permanent move (returns 301): location /old-page { return 301 /new-page; }
# For wildcard moves with query string preservation: location /old-section/ { return 301 /new-section/$request_uri; }
# For auth-gated routes, 302 is correct: location /dashboard { auth_request /auth-check; error_page 401 = @login_redirect; }
location @login_redirect { return 302 /login?next=$request_uri; } ```
After applying, validate with `curl -I https://yourdomain.com/path` — you should see the corrected status header. If you are running behind Cloudflare or a similar CDN, remember to purge cache and check that the upstream-only response matches what edge users will see.
For Apache (still common on legacy WordPress and Magento hosts), the equivalent goes in your `.htaccess` or virtualhost config:
# Wrong (defaults to 302): # Redirect /old-page /new-page
# Right — explicit permanent redirect: Redirect 301 /old-page /new-page
# Or with mod_rewrite for pattern matching: RewriteEngine On RewriteRule ^old-section/(.*)$ /new-section/$1 [R=301,L]
# For temporary redirects (correct use of 302): RewriteCond %{HTTP_HOST} ^example\.com$ RewriteRule ^maintenance$ /maintenance.html [R=302,L] ```
Reload with `sudo apachectl graceful`. On shared hosting where you cannot reload, the `.htaccess` change takes effect on the next request — but you should still flush any opcode cache (LiteSpeed, OPcache) to be sure.
302 redirects are the single most common SEO mistake we see during technical audits. The mechanism: when Googlebot encounters a 302, it follows the redirect but keeps the old URL in its index, expecting the redirect to be temporary. PageRank, internal links, backlinks, and historical authority continue to be associated with the old URL. If the redirect is actually permanent (you migrated /old-page to /new-page forever), you have effectively orphaned the new URL — it has no inherited authority. We have audited Ottawa sites where a CMS migration converted hundreds of 301s into 302s and traffic dropped 40% within 60 days. Google has historically said it tries to detect long-running 302s and treat them as 301s after enough time passes — but 'enough time' is undefined and behaviour is inconsistent. Do not rely on Google to fix your redirects. Use the right code from the start. Audit redirects quarterly. The correct rule of thumb: if you would tell a human visitor 'this URL has moved permanently,' use 301. If you would tell them 'this URL is temporarily over there,' use 302.
The most painful 302 issue we have seen on the Ottawa market involved a law firm that rebuilt its site on a new CMS in 2024. The new CMS framework defaulted to 302 for everything, including the 600+ redirects from old practice-area URLs to new ones. The site had built up 8 years of organic equity. Within 12 weeks of launch, organic traffic was down 38%. We diagnosed the redirect codes, switched all 600 to 301, and within another 8 weeks Google had reindexed and equity was largely restored — but those 12 weeks of lost traffic represented roughly $40,000 of lost client work for a high-value legal vertical. The fix took an afternoon. The problem could have been avoided in 30 minutes during pre-launch QA. We now include a redirect-code audit as a non-negotiable step in every site migration we touch. See our SEO services page for what a proper migration looks like, and our contact page if you are about to migrate and want a second pair of eyes.
If the fix above does not resolve the 302 response, the issue is usually one layer deeper than the web server: an upstream application, a misconfigured load balancer, or an origin shield rule on the CDN. At that point a full HTTP trace (via `curl -v` or a Charles/Wireshark capture) is the fastest path to root cause. If you would rather hand the diagnosis to a senior engineer, book a free call and we will walk through the request path with you. For broader site health, see our SEO services and our free PageSpeed audit tool.
301 is permanent — Google should update its index, transfer authority, and treat the new URL as canonical. 302 is temporary — Google should keep the old URL indexed and continue attributing authority to it.
Sometimes, after an extended period, but the behaviour is inconsistent and not documented. Do not rely on it. Use the correct status code from day one.
When used incorrectly for permanent moves, yes — significantly. 302 prevents authority transfer to the new URL, which can cost you 30%+ of organic traffic on a migration. Used correctly for temporary scenarios (auth gates, A/B tests, maintenance pages), it has no negative effect.
308 Permanent Redirect is the strict version of 301 that requires the request method to be preserved (a POST stays a POST). For most SEO use cases, 301 is what you want — it is universally supported and behaves identically for GET requests.