301 Moved Permanently
The resource has a new permanent URL, given in the Location header.1 Clients should use the new URL from now on, and search engines move the old URL's ranking over to it.
- Class 3xx redirection
- Cacheable by default
- Header Location
Open cURL Builder Build the request with -L to follow the redirect chain.
When you see it
- The site moved to HTTPS, dropped or added
www, or changed how it treats a trailing slash. - A page or an API route was renamed, and the old path forwards to the new one.
- A framework normalises URLs (lower case, trailing slash) and redirects every other spelling.
What to do
- As a client, follow it (
curl -L; most HTTP libraries do it by default) and update the URLs you store, so you stop paying for the extra round trip. - Browsers cache a 301 with no expiry, so a wrong one can stay with visitors until their cache is cleared. Try a new redirect as a 302 first and switch it to 301 once the target is final.
- For a POST or PUT, use 308. Clients have long turned a redirected POST into a GET and dropped the body, and 301 still allows that.2
- Point every redirect straight at the final URL. A chain (
httptohttpstowww) costs a round trip per hop.
301 or 308?
Both are permanent. 308 forbids changing the method,3 so a POST stays a POST, body included. For pages fetched with GET the two behave the same; for API endpoints, 308 is the safe choice.
301 or 302?
302 says the move is temporary:4 search engines keep the old URL indexed and browsers don't cache the redirect. Use it for maintenance pages and experiments, not for a move you mean to keep.
Example
GET /blog/old-post HTTP/1.1 Host: example.com HTTP/1.1 301 Moved Permanently Location: https://example.com/blog/new-post Content-Length: 0
Sources
- 1 RFC 9110, HTTP Semantics, section 15.4.2. rfc-editor.org ↩︎
- 2 RFC 9110, HTTP Semantics, section 15.4. rfc-editor.org ↩︎
- 3 RFC 9110, HTTP Semantics, section 15.4.9. rfc-editor.org ↩︎
- 4 RFC 9110, HTTP Semantics, section 15.4.3. rfc-editor.org ↩︎