< HTTP/1.1 308 Permanent Redirect308 Permanent Redirect
Permanent redirect that preserves the HTTP method. Learn when to use 308 instead of 301 for method-sensitive permanent redirects.
- 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
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()withpermanent: trueemits 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
Authorizationin 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
- Ship the new endpoint and keep the old one answering 308 to it.
- Log traffic still hitting the old path and announce a deprecation date.
- Update SDKs and docs to the new URL.
- Only after traffic drops, consider returning 410 Gone.
Related
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
Related
301 vs 308: Permanent Redirects and POST Requests
301 vs 308: both signal a permanent move, but only 308 preserves POST. Compare browser handling, Google indexing, cache controls, and curl traces.
300 Multiple Choices
The request has multiple possible responses. Learn when to use 300 Multiple Choices for content negotiation and alternative resource locations.
303 See Other
Redirect to a different resource using GET. Learn when to use 303 to prevent form resubmission and implement the Post-Redirect-Get pattern.
307 Temporary Redirect
Temporary redirect that preserves the HTTP method. Learn when to use 307 instead of 302 for method-sensitive redirects.
HTTP 302 Found: Temporary Redirect
Learn what 302 redirect means, when to use temporary vs permanent redirects, and how 302 differs from 301, 307, and 308.