HTTP 308 Permanent Redirect: 301's Stricter Sibling
We were versioning an API — moving every endpoint from /api/ to /api/v2/ — and the plan said "301 everything, clients will follow." Two integration partners broke within the hour. Their HTTP libraries followed the 301 by re-sending as GET, exactly as the spec permits, and our POST endpoints started receiving bodyless GET requests that had nowhere to go. We swapped the redirects to HTTP 308 and both integrations recovered without the partners changing a line of code.
That's the niche 308 fills: a permanent redirect with a contract strong enough to trust with non-GET traffic.
What the 308 status code guarantees
A 308 Permanent Redirect makes two promises at once. Like a 301, it declares the move permanent — clients should update their references, caches may store the redirect, and search engines should transfer the URL's standing to the destination. Unlike a 301, it forbids the client from changing the request method or dropping the body when it follows the redirect. A POST stays a POST. A DELETE stays a DELETE. The payload arrives intact at the new URL.
It's the fourth corner of a two-by-two grid: temporary and loose is 302, temporary and strict is 307, permanent and loose is 301, permanent and strict is 308.
The method problem 301 never solved
The 301 spec technically says the method shouldn't change, but it also acknowledges that clients historically convert POST to GET — and that behavior is grandfathered in. So "301 a POST" has undefined behavior in practice: some HTTP clients preserve the method, browsers generally don't, and you can't control which library your API consumers use. When the redirected traffic is all GETs — normal web pages — this ambiguity costs nothing, which is why 301 remains the right default for page moves. When redirected traffic includes writes, the ambiguity is a data-loss bug waiting for the right client library to trigger it.
Where a 308 earns its keep
- API endpoint migrations. The canonical use case. Old endpoints answer 308 with the new path in
Location, well-behaved clients follow with method and body intact, and you keep the redirects up until traffic to the old paths dies off. - Form handlers that moved for good. If third-party sites or old cached pages still POST to your legacy form URL, a 308 forwards the submission instead of orphaning it.
- Webhook receiver moves. You often can't make every sender update their configured URL promptly. A 308 keeps the payloads flowing to the new receiver in the meantime.
- Infrastructure that standardizes on it. Some platforms and frameworks emit 308 for things like trailing-slash normalization or HTTP-to-HTTPS upgrades — Next.js, for instance, uses 308 for its permanent redirects out of the box. Nothing wrong with that; it's a superset of 301's guarantees.
Serving and verifying a 308
Any modern server can emit one. nginx:
location = /api/old-endpoint { return 308 /api/v2/endpoint; }
Apache needs mod_rewrite for arbitrary status codes: RewriteRule ^api/old-endpoint$ /api/v2/endpoint [R=308,L]. Most CDNs and edge platforms offer 308 in their redirect rule dropdowns now.
Then prove the contract holds end to end. Send a POST with a body at the old URL and follow the redirect:
curl -sL -X POST -d '{"test":1}' -H "Content-Type: application/json" https://example.com/api/old-endpoint -w "\nfinal: %{url_effective}"
Check your application logs at the destination: the request should arrive as a POST with the JSON body present. If it lands as a GET, something in the middle — a proxy, a WAF, an old client — rewrote the redirect, and that's worth knowing before your API consumers find out for you.
Does Google treat 308 like 301?
Yes. Google has confirmed 308 is processed as a permanent redirect: the destination URL replaces the origin in the index and ranking signals consolidate onto it, same as a 301. Crawlers fetch pages with GET anyway, so the method-preservation clause never even comes into play for indexing. That means there's no SEO reason to prefer either code — pick based on your traffic. Pages: 301, purely for maximum compatibility with ancient clients. Anything that receives POSTs: 308.
The one SEO caution is the same one every redirect carries: keep the map clean. A 308 hopping into a 301 hopping into another 308 still works, but every extra hop in a redirect chain adds latency and burns crawl requests. Point old URLs directly at their final destination.
The compatibility caveat
308 entered the spec in 2014 (RFC 7538), decades after 301. Every current browser, curl, and mainstream HTTP library handles it correctly, but genuinely old clients — think embedded systems, legacy Java 6 applications, ancient monitoring probes — may not recognize the code and will treat it as an error instead of following it. The spec anticipated this: servers are encouraged to include a small HTML body with a link to the new location as a fallback. For public-facing web pages where you can't predict the client population, this is the honest argument for defaulting to 301. For APIs where you know your consumers run maintained HTTP stacks, 308 is safe.
Before and after any endpoint migration, crawl your site to confirm every redirect resolves in a single hop to a 200 — it's the fastest way to catch the half-migrated URL someone forgot.
Frequently Asked Questions
When should I use 308 instead of 301?
Use 308 when the redirected URL receives non-GET requests — API endpoints, form handlers, webhook receivers — because 308 forbids clients from converting a POST into a GET while following the redirect. For ordinary web page moves where all traffic is GET, 301 behaves identically and has broader legacy-client support.
Is HTTP 308 as good as 301 for SEO?
Yes — Google processes both as permanent redirects, replacing the old URL in the index and consolidating signals onto the destination. Since crawlers fetch with GET, the method-preservation difference between the two codes never affects indexing. Choose based on what kind of traffic hits the URL, not on SEO.
Can old browsers or clients fail on a 308?
Modern browsers and HTTP libraries all support it, but 308 was only standardized in 2014, so very old clients — legacy Java stacks, embedded devices, aging monitoring tools — may treat it as an unknown error rather than following it. Including a small HTML body with a link to the new URL gives those clients a manual fallback.
Try WebsiteChecker.Tech Free
Run a free technical SEO audit on any website. Get a client-ready report in minutes.
Start Free Scan