How HTTP Works
3xx · Redirection
< HTTP/1.1 308 Permanent Redirect

308 Permanent Redirect

Permanent redirect that preserves the HTTP method. Learn when to use 308 instead of 301 for method-sensitive permanent redirects.

Reviewed 2 min readintermediate2 sourcesTry itMarkdown
Cacheable
Yes, by default
Client action
Follow Location, same method; update links
Usually sent by
Origin app, reverse proxy or CDN rule
Spec
RFC 9110 §15.4.9
Often confused with
301, 307
On this page

TL;DR: 308 Permanent Redirect is 301 with a guarantee: the client must repeat the same method and body at the new Location, and the move is permanent and cacheable. Use it when an API endpoint or form target moves and POST must stay POST.

What it means

PUT /v1/users/42 HTTP/1.1
Host: api.example.com

HTTP/1.1 308 Permanent Redirect
Location: https://api.example.com/v2/users/42

The client retries PUT /v2/users/42 with the same body (RFC 9110 section 15.4.9, originally RFC 7538). Like 301, it is cacheable by default, so clients may skip the old URL afterwards.

301 or 308?

  • Moving GET pages for SEO: either works. Google treats 301 and 308 as the same permanent signal. 301 is the more common choice and understood by every tool.
  • Anything with a request body (POST, PUT, PATCH, DELETE): use 308. A 301 lets clients turn POST into GET, silently dropping the body and often producing a confusing 404 or 405 at the new URL.
  • Next.js redirects() with permanent: true emits 308, not 301.
  • A few very old clients and embedded SDKs do not understand 308 and do not follow it. Rare today, but check legacy integrations.

Gotchas

  • Caching makes mistakes sticky. Browsers cache 308 like 301. Test with 307 first and switch once certain, or bound it with Cache-Control: max-age=....
  • Request bodies must be replayable; streaming uploads often cannot follow a 308 automatically.
  • Cross-origin redirects drop Authorization in browsers and most clients, so authenticated API calls may reach the new host as 401.
  • Preflight requests cannot be redirected. A CORS preflight answered with 308 fails with “Redirect is not allowed for a preflight request”.

Implementation

nginx

location /v1/ {
    return 308 https://api.example.com/v2$request_uri;
}

Express

// Express 5 syntax; in Express 4 use '/v1/*'
app.all('/v1/*splat', (req, res) => {
  res.redirect(308, `/v2${req.originalUrl.slice(3)}`)
})

Apache

RedirectMatch 308 ^/v1/(.*)$ /v2/$1

Reproduce with curl

curl -sI https://api.example.com/v1/users/42
# HTTP/2 308
# location: https://api.example.com/v2/users/42

# Confirm the method survives the hop
curl -sv -L -X POST -d '{"a":1}' -H 'Content-Type: application/json' \
  https://api.example.com/v1/users 2>&1 | grep -E '^> (POST|GET)'

Both request lines should be POST. If the second is GET, the redirect was a 301/302 or the client rewrote it.

Migration plan

  1. Ship the new endpoint and keep the old one answering 308 to it.
  2. Log traffic still hitting the old path and announce a deprecation date.
  3. Update SDKs and docs to the new URL.
  4. Only after traffic drops, consider returning 410 Gone.

Frequently asked questions

What does 308 Permanent Redirect mean?

308 means the resource has permanently moved to a new URL and the client must use the same HTTP method when accessing the new location. It is the method-preserving version of 301.

What is the difference between 308 and 301?

308 guarantees the HTTP method is preserved (POST stays POST). 301 may change POST to GET in some browsers. Use 308 for API migrations where method preservation is critical.

When should I use 308 vs 307?

Use 308 for permanent redirects where the method must be preserved. Use 307 for temporary redirects. Both preserve the HTTP method, but 308 can be cached long-term.

Does 308 transfer SEO value like 301?

Yes, 308 transfers PageRank and SEO value to the new URL just like 301. Search engines treat both as permanent redirects for ranking purposes.

Sources

  1. MDN Web Docs: 308 Permanent Redirectdeveloper.mozilla.org
  2. RFC 9110: 308 Permanent Redirectrfc-editor.org

Keep going

Browse /search