HTTP Redirect Status Codes: 301, 302, 307, 308

Comprehensive reference for all HTTP redirect status codes: 301 Moved Permanently, 302 Found, 303 See Other, 307 Temporary Redirect, 308 Permanent Redirect. When to use each and browser behavior differences.

HTTP defines five redirect status codes in the 3xx range, and each one tells browsers and search engines something different about why and how a resource has moved. Choosing the wrong one can break form submissions, lose SEO equity, or confuse caching layers.

This is the complete reference for every HTTP redirect status code you will encounter in production.

The Complete Status Code Table

CodeNamePermanenceMethod PreservedCommon Use
301Moved PermanentlyPermanentNo (may change to GET)Domain migrations, URL restructuring
302FoundTemporaryNo (may change to GET)Temporary redirects, A/B tests
303See OtherTemporaryAlways changes to GETPost-form-submission redirects
307Temporary RedirectTemporaryYes (must preserve method)API redirects, temporary moves with POST
308Permanent RedirectPermanentYes (must preserve method)API endpoint migrations, permanent moves with POST

The key distinction most developers miss is the method preservation column. It is the entire reason 307 and 308 exist.

301 Moved Permanently

The workhorse of redirects. Use it when a resource has permanently moved to a new URL.

HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page

Browser behavior: Browsers may change the request method from POST to GET when following a 301. This is technically a violation of the HTTP spec, but every major browser does it. This means a 301 is unsafe for redirecting POST requests if you need the POST body preserved.

SEO behavior: Search engines transfer link equity to the new URL and eventually de-index the old URL. This is the strongest signal you can send that a URL has permanently moved.

Caching: Browsers cache 301 redirects aggressively. Some browsers will continue following the cached redirect even after you remove it from the server. This is by design, as the spec says permanent means permanent.

301 caching can bite you

If you 301 a URL to the wrong destination, fixing it on the server is not enough. Users who already visited will have the incorrect redirect cached. You may need to use cache-busting headers or wait for the browser cache to expire.

302 Found

The most misused redirect code. Originally defined as "Moved Temporarily" in HTTP/1.0, renamed to "Found" in HTTP/1.1. Use it when a resource is temporarily at a different URL.

HTTP/1.1 302 Found
Location: https://example.com/temporary-page

Browser behavior: Like 301, browsers may change POST to GET when following a 302. This was the original spec violation that led to the creation of 307.

SEO behavior: Search engines keep the old URL in their index. Link equity may not transfer to the temporary URL. Google will eventually treat a long-standing 302 as a 301, but the timeline is unpredictable.

Caching: Browsers typically do not cache 302 redirects, or cache them only briefly. This is appropriate since the redirect is temporary.

303 See Other

The most misunderstood redirect code. 303 was introduced in HTTP/1.1 specifically for the Post/Redirect/Get (PRG) pattern.

HTTP/1.1 303 See Other
Location: https://example.com/confirmation

When to use it: After processing a form submission (POST), redirect the user to a confirmation page using 303. This explicitly tells the browser to use GET for the redirect target, preventing the "resubmit form?" dialog on page refresh.

User submits form --> POST /checkout
Server processes   --> 303 See Other, Location: /order/12345
Browser follows    --> GET /order/12345 (always GET, by spec)

SEO behavior: Search engines treat 303 like a temporary redirect. The original URL stays indexed.

Trace your redirect chains

Find redirect loops, broken chains, and unnecessary hops instantly.

307 Temporary Redirect

Created to fix the 302 method-changing problem. A 307 is a temporary redirect that must preserve the HTTP method.

HTTP/1.1 307 Temporary Redirect
Location: https://example.com/temporary-endpoint

Browser behavior: If the original request was a POST, the browser must send a POST to the new URL. The request body is preserved. Browsers will typically show a confirmation dialog before resending a POST.

When to use it: Temporarily redirecting API endpoints or any URL that receives POST/PUT/DELETE requests where you need the request body and method preserved.

POST /api/v1/users --> 307 --> POST /api/v2/users
                               (body preserved, method preserved)

POST /api/v1/users --> 302 --> GET /api/v2/users
                               (body LOST, method CHANGED)

SEO behavior: Same as 302. Temporary. Old URL stays indexed.

308 Permanent Redirect

The permanent version of 307. A 308 is a permanent redirect that must preserve the HTTP method. Added in RFC 7538 (2015).

HTTP/1.1 308 Permanent Redirect
Location: https://example.com/new-endpoint

Browser behavior: Same method preservation as 307, but the redirect is permanent. Browsers cache it aggressively like a 301.

When to use it: Permanently redirecting API endpoints that receive POST/PUT/DELETE requests. Also useful for HSTS enforcement where you need the original method preserved.

Browser support: All modern browsers support 308. Internet Explorer does not, but IE is no longer relevant for most applications.

Decision Guide

Use this to pick the right status code:

Is the move permanent?
  |
  +-- YES --> Does the endpoint receive POST/PUT/DELETE?
  |             |
  |             +-- YES --> 308 Permanent Redirect
  |             |
  |             +-- NO ---> 301 Moved Permanently
  |
  +-- NO ---> Is this after a form submission (PRG pattern)?
                |
                +-- YES --> 303 See Other
                |
                +-- NO ---> Does the endpoint receive POST/PUT/DELETE?
                              |
                              +-- YES --> 307 Temporary Redirect
                              |
                              +-- NO ---> 302 Found

Status Codes You Should NOT Use for Redirects

300 Multiple Choices: Technically a redirect code, but it presents the user with multiple options rather than automatically redirecting. Almost never used in practice.

304 Not Modified: Not a redirect. It tells the browser to use its cached version. No Location header is involved.

305 Use Proxy: Deprecated for security reasons. Do not use.

306 (Unused): Reserved. Does nothing.

Implementation Examples

Nginx

# 301 - Permanent redirect
server {
    listen 80;
    server_name old.example.com;
    return 301 https://new.example.com$request_uri;
}

# 302 - Temporary redirect
location /maintenance {
    return 302 /status-page;
}

# 307 - Temporary, method-preserving
location /api/v1/ {
    return 307 /api/v2/$request_uri;
}

Apache .htaccess

# 301 - Permanent redirect
Redirect 301 /old-page https://example.com/new-page

# 302 - Temporary (default if you omit the code)
Redirect /temp-page https://example.com/other-page

# 307 - Temporary, method-preserving
RewriteRule ^api/v1/(.*)$ /api/v2/$1 [R=307,L]

How to Verify Status Codes

# Check a single URL
curl -I https://example.com/some-page

# Follow the full chain and show each hop
curl -v -L https://example.com/some-page 2>&1 | grep "< HTTP"

The response will show the exact status code for each hop in the redirect chain. Verify that each hop uses the code you intended.


The right status code is a single decision that echoes through every crawler, cache, and browser that touches your URL.

Never miss a broken redirect

Trace redirect chains and detect issues before they affect your users and SEO. Free instant tracing.