HTTP 301 vs 302 vs 307 vs 308: which redirect should you use?
Five redirect codes, two questions: is the move permanent, and must the request method stay the same? Answer those and the right code picks itself.
The table
| Code | Name | Permanent? | POST stays POST? | Cached by browsers? |
|---|---|---|---|---|
| 301 | Moved Permanently | Yes | Not guaranteed: browsers change it to GET | Yes, often for a long time |
| 302 | Found | No | Not guaranteed: browsers change it to GET | Only if cache headers say so |
| 303 | See Other | No | No: always becomes GET (that's the point) | Only if cache headers say so |
| 307 | Temporary Redirect | No | Yes, method and body kept | Only if cache headers say so |
| 308 | Permanent Redirect | Yes | Yes, method and body kept | Yes, like 301 |
Why the overlap? The original rules for 301 and 302 said the method should be kept, but early browsers turned POST into GET anyway, and so many sites relied on that that it became the accepted behaviour. 307 and 308 were added later to mean “and this time really keep the method”.
Which one, in practice
- Changed a URL, moved to a new domain, http→https, adding or removing www: 301. Every browser, crawler and tool understands it.
- API endpoint moved, and clients send POST, PUT or DELETE: 308, so the body isn't silently dropped.
- Sale page, maintenance page, A/B test, “log in first”: 302 (or 307 for non-GET requests).
- After a form submission: 303 to a “thanks” or results page, so refreshing doesn't resubmit the form (the Post/Redirect/Get pattern).
What about SEO?
Google treats 301 and 308 as strong signals that the new URL should replace the old one in search results, and 302 and 307 as signals to keep the old URL. Google says permanent and temporary redirects both pass ranking signals, so the choice is about which URL you want shown. Avoid chains (A→B→C): point old URLs straight at the final address, and update your internal links so they don't redirect at all.
The caching trap
Browsers can remember a 301 or 308 for a very long time, sometimes until the cache is cleared, without asking the server again. If you 301 by mistake, people who saw it keep being redirected even after you remove it. While testing, use 302, and switch to 301 once you're sure. You can also send Cache-Control: max-age=3600 with a 301 to limit how long it sticks.
Copy-ready examples
# nginx: whole site to https
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
# nginx: one page
location = /old-page { return 301 /new-page; }
# Apache (.htaccess)
Redirect 301 /old-page /new-page
# Express (res.redirect defaults to 302)
res.redirect(301, '/new-page');
# Flask (redirect defaults to 302)
return redirect('/new-page', code=301)
For every other status code, including 303, 304 and the odd ones proxies send, see Anvil’s free HTTP status lookup.
Check what a URL really does
curl -sI https://example.com/old-page # first hop: status + Location
curl -sIL https://example.com/old-page | grep -iE '^(HTTP|location)' # every hop
A 307 with “Non-Authoritative-Reason: HSTS” in Chrome's Network tab is not from your server: the browser upgraded http to https itself because the site uses HSTS. If a redirect target contains odd characters, check it with the URL encoder. Want to see codes in action? Wirebook's status-code lesson lets you fire real ones.
Stuck in a loop where the browser says redirected you too many times? See ERR_TOO_MANY_REDIRECTS for how to find and break it. Checking where a link really leads before you click? See how to tell who owns a link.
Related
download won't resume (redirects + Range)
Questions
Is a 301 or 302 better for SEO?
Neither is better in general. Use 301 when the move is permanent so the new URL replaces the old one in results; use 302 when the old URL should stay indexed. Both pass ranking signals.
What is the difference between 301 and 308?
Both are permanent. With 308 the browser must repeat the same method and body, so a POST stays a POST. With 301 browsers usually switch to GET.
What is the difference between 302 and 307?
Both are temporary. 307 guarantees the method and body are kept; 302 in practice turns POST into GET.
How do I undo a cached 301?
You can't force browsers to forget it. Visitors need to clear their cache, or the old URL needs to redirect back. Test with 302 first, or send a short Cache-Control max-age with the 301.
Published .