HTTP 3xx redirect status codes
The 3xx class tells the client that further action — usually following a Location URL — is needed to complete the request. The nuances matter: some redirects are permanent and pass SEO signals, others are temporary; some preserve the original HTTP method and body, others quietly rewrite it to GET. Pick the wrong one and you can break a POST, lose search rankings, or create redirect loops. Search the reference above by code or keyword to compare permanence, method handling, and caching.
The two dimensions that separate the codes
Every redirect code sits somewhere on two independent axes:
Permanence:
- Permanent (
301,308) — the resource has moved for good. Browsers should update bookmarks, and search engines should transfer ranking signals (link equity) to the new URL. - Temporary (
302,303,307) — the resource is temporarily elsewhere. Browsers do not update bookmarks, and search engines keep indexing the original URL.
Method preservation:
- Rewrite to GET —
303always switches the method toGET.301and302historically allowed agents to switchPOSTtoGET, and most browsers still do. - Preserve method —
307and308guarantee the original method and body survive the redirect unchanged. APOSTto a307target is still aPOST.
Quick decision guide
| Scenario | Code | Why |
|---|---|---|
| Permanent domain move (preserve POST) | 308 | Permanent + method-safe |
| Permanent URL restructure (GET pages) | 301 | Permanent; POST→GET rewrite is acceptable |
| Temporary maintenance page | 307 | Temporary; preserves method |
| Form POST → result GET (Post/Redirect/Get) | 303 | Always redirects to GET |
| Redirect while keeping POST intact temporarily | 307 | Temporary + method-safe |
| Signal cached content is still fresh | 304 | Not a navigation redirect |
How it works
A redirect response carries a Location header pointing to the new target. The browser then issues a fresh request to that URL. 304 Not Modified is the odd one out — it is part of conditional caching requests, not navigation, and returns no body. The server sends it to answer an If-None-Match or If-Modified-Since conditional request when the cached copy is still valid.
Common mistakes
- Using
302for permanent moves — search engines treat it as temporary and keep indexing the old URL indefinitely. - Redirect chains — A→B→C wastes round trips, dilutes link equity, and slows page loads. Test with
curl -ILto see the full chain and collapse it to a single hop. - Not including
Retry-Afteron503redirects —503withLocationis unusual but sometimes used for maintenance; if you use a302for maintenance, crawlers stop indexing the original URL. - Redirecting POST to a new location without
303— use303 See Otherafter a form submission so a page refresh re-fetches the confirmation page withGETrather than resubmitting the form.
Caching behaviour
301and308are cacheable by default — browsers and caches store them without an explicitCache-Control. If the redirect might change, sendCache-Control: no-store.302and307are not cached by default unless explicit freshness headers are included.304is used in place of a body; the client assembles the response from its cache.