A 302 is not really an error, it is the HTTP status for Found, a temporary redirect, and it only becomes a problem when the redirect is unintended, endless, or standing in for a permanent move.
Most people meet a 302 as an alarming line in a log or a crawler report. The question is never whether it exists but whether the site meant to send it.
Table of contents
- What a 302 response contains
- 302 versus 301, 307 and 308
- When a 302 is the wrong status
- Redirect loops and the browser error that comes with them
- 302 and SEO: how much does it really cost
- Setting the right status in your stack
- Reading 302s in logs and crawl reports
- How this fits the rest of the stack
- FAQ
What a 302 response contains
A 302 response is a short message with a status line and a Location header. The status says the resource lives at another URL for now. The Location header says where. A browser reads it, follows to the new address, and the address bar changes. The user rarely notices.
HTTP/1.1 302 Found
Location: https://example.com/login?next=/account
Cache-Control: no-store
The key word is temporary. A 302 tells clients to keep using the original URL in future, because the redirect might not apply next time. That is exactly right for a login wall, a regional landing page, a maintenance notice or an A/B test. It is exactly wrong for a page that has moved for good.
The MDN page on 302 Found is the canonical definition if you need to cite one. Alongside it sit the other redirect codes, and the useful way to hold them in your head is two questions: is the move permanent, and may the request method change? 301 is permanent and may rewrite POST to GET. 302 is temporary and historically may rewrite it too. 307 is temporary and keeps the method. 308 is permanent and keeps the method.
302 versus 301, 307 and 308
This table is the whole decision.
| Code | Permanent | Method preserved | Typical use |
|---|---|---|---|
| 301 | Yes | Not guaranteed | Moved pages, domain changes, HTTP to HTTPS |
| 302 | No | Not guaranteed | Login redirects, short-term moves |
| 307 | No | Yes | Temporary redirect of a form post or API call |
| 308 | Yes | Yes | Permanent move of an API endpoint |
The method point matters more than people expect. Imagine an API client that posts a payment to /v1/charges and gets a 302 to a new path. Many clients re-send the redirected request as a GET. The charge quietly never happens. Using 307 or 308 tells the client to repeat the POST with the same body.
For ordinary web pages the choice is simpler. If the old URL is never coming back, use 301. If it is genuinely temporary, use 302. Where you are redirecting a non-GET request, reach for 307 or 308.
A 303 deserves a mention because it is the deliberate cousin: it means redirect with a GET after a POST. That is the standard Post/Redirect/Get pattern for form submissions and is a good use of a temporary redirect.
When a 302 is the wrong status
Three patterns account for most real problems.
A permanent move shipped as a 302. A site migrates to a new domain or restructures its URLs and the redirect rule defaults to temporary. Search engines treat a 302 as a short-term detour, so the old URL can keep its place in results while the new one is slow to pick up the signals. Google generally handles long-lived 302s as permanent in the end, but you should not rely on being guessed correctly. Say what you mean.
The framework default. Many frameworks and platforms emit 302 unless you ask for something else. A redirect helper in your web framework, a rewrite in a hosting panel, a plugin that forces a trailing slash: check the status, because the default is frequently temporary.
A 302 on a URL that never changes. If every request to /pricing returns 302 to /plans, and always will, that is a permanent move wearing the wrong status. Crawlers keep requesting the old URL and you spend crawl budget on a hop that carries no information.
To audit a site, crawl it and list every 302. For each, ask whether it will ever stop. If the answer is no, change it to 301 or 308.
Redirect loops and the browser error that comes with them
The 302 most people actually complain about is the one that never stops. The browser follows a redirect, lands on a URL that redirects again, and after about twenty hops gives up with a too many redirects error.
Loops almost always have one of three roots:
- HTTP and HTTPS disagreeing. The app forces HTTPS, a proxy in front terminates TLS and forwards plain HTTP, and the app does not know the original scheme. It redirects to HTTPS forever. The fix is to trust the forwarded protocol header from the proxy.
- Trailing slash fights. One rule adds the slash, another removes it.
- Authentication redirects without a stable exit. A page redirects to login, login redirects back, and a missing or unreadable cookie means the session never sticks.
The diagnostic is a single command:
curl -sIL --max-redirs 10 https://example.com/account | grep -iE '^(HTTP|location)'
That prints every hop with its status and target, and you can see the cycle immediately. The existing guide on too many HTTP redirects walks through the common causes in depth, and the Cloudflare error 502 post is useful when a proxy layer is part of the story.
302 and SEO: how much does it really cost
Honest answer: less than the folklore suggests and more than zero. A single temporary redirect on a login page costs nothing, because the page should not rank anyway. A permanent URL change implemented as 302 can delay consolidation of ranking signals onto the new address.
The practical rules are short. Use 301 when a page has permanently moved. Keep redirect chains to a single hop, because every extra hop adds latency and dilutes crawl efficiency. Update internal links to point at the final URL so users and crawlers skip the redirect entirely. And keep the old redirect in place for a long time, since external links will keep pointing at it for years.
Redirects also affect performance. Each one costs a round trip before the browser even begins fetching the real page. A chain of three redirects on a mobile connection can add a visible delay to your first load. Measure the hop count with the curl command above and flatten it.
Setting the right status in your stack
How you set the status depends on where the redirect lives.
At the web server, Nginx takes the status as part of the directive:
# permanent
return 301 https://example.com$request_uri;
# temporary
return 302 /maintenance;
In application code, pass the status explicitly instead of trusting the default. In Express you write res.redirect(301, url). In Django, redirect(url, permanent=True) issues a 301. In Next.js, redirects in config accept permanent: true, which emits a 308, and permanent: false, which emits a 307.
On static hosting the redirect rules live in configuration. RunxBuild static sites support redirects, rewrites and SPA fallback with a status you set per rule, documented in the static redirects docs. Prefer rules in config over client-side JavaScript redirects, because crawlers and link previews follow HTTP statuses and ignore scripts.
After any change, re-run the curl check and confirm the status and the hop count. Then check your sitemap lists the final URLs, not the redirecting ones.
Reading 302s in logs and crawl reports
In an access log a 302 is an ordinary line, so the trick is knowing which ones deserve attention. Filter for 302 responses and group by path. Three shapes stand out. A high count on one path usually means a login wall being hit by an unauthenticated crawler or monitor, which is fine. A high count on a static asset path means something is redirecting your images or scripts, which is almost always a misconfiguration that adds a round trip to every page view. And a 302 on the homepage means the root URL is hopping to a language or region page on every visit.
Crawl tools report the same thing from the outside. A site audit will list redirecting URLs, internal links that point at them, and chains longer than one hop. Fix the internal links first, because they are entirely under your control and removing them eliminates the redirect for every visitor at once.
Keep a short note of intentional redirects: what they do and why they are temporary. Six months later, a temporary redirect nobody remembers is the most common reason a 302 is still live.
How this fits the rest of the stack
Redirect rules look free until a migration multiplies them, and the cost of an extra hop adds up across millions of requests. If you are planning a move and want to see what the destination actually costs to run, the RunxBuild hosting calculator puts the line items in one place. When the new home is ready, the RunxBuild dashboard is where you create it and point a custom domain at it.
Useful related references:
- 302 Found: The Temporary Redirect, and When It Is the Right Answer
- HTTP 302: What It Actually Means, and Why You Probably Wanted 301 or 307
- What Is a 401 Error: Unauthenticated, Not Unauthorised
- Redirects on RunxBuild
FAQ
Is a 302 error bad?
Not by itself. A 302 is a normal temporary redirect. It is a problem only when it is unintended, forms a loop, or is used for a page that moved permanently, in which case a 301 or 308 is the correct status.
What is the difference between a 301 and a 302?
A 301 says the move is permanent and clients should update their records. A 302 says it is temporary and the original URL remains the canonical one. Use 301 for permanent changes and 302 for short-term ones like login redirects.
Does a 302 redirect hurt SEO?
A single 302 on a page that is supposed to be temporary is harmless. Using a 302 for a permanent move can slow how quickly ranking signals transfer to the new URL, so use a 301 when the old address is retired.
Why do I get too many redirects with a 302?
The redirect target is redirecting back, often because HTTPS is forced behind a proxy that forwards plain HTTP, or because two rules disagree about the trailing slash. Trace the hops with curl and fix the rule that closes the cycle.
When should I use 307 instead of 302?
Use 307 when the redirected request is not a simple GET and the method and body must be preserved, such as a POST to an API. A 302 may be re-sent as a GET by some clients, which silently drops the payload.