301 Moved Permanently
The HTTP 301 Moved Permanently status code is returned by the server to indicate the resource has been assigned a new permanent location.
The response is cacheable by default. To override this behavior, include appropriate Cache-Control headers.
Usage
When the 301 Moved Permanently status code is received, clients are expected to update stored links to the new URI. The new URI is specified by the Location header and is used by the client for automatic redirection.
This response is common when servers migrate to a new domain or reorganize their internal file structure with no plan to revert to the former URI.
Method change
User agents are permitted to change POST to GET on a 301 redirect for historical reasons. Most browsers do exactly this, making the method change a de facto standard behavior. The 308 status code was created specifically to guarantee method preservation without ambiguity. For APIs and modern applications, prefer 308 for permanent redirects when the original method must be kept.
SEO impact
Google treats a 301 as a strong signal the redirect target is indexed. Ranking signals transfer from the old URL to the new one. Use 301 for permanent URL changes, domain migrations, and HTTPS upgrades. Google follows up to 10 redirect hops. Content from intermediate redirect URLs is ignored. Redirecting deleted URLs to the homepage or a generic category page with a 301 is detected by Google as a soft 404. Bing transfers ranking value from the old URL to the new on a 301, though the new URL still builds trust independently. If a 301 changes destination on each crawl, Bing treats the redirect as a 302 Found.
Example
The client requests an HTML resource. The server responds with 301 Moved Permanently and includes the new URI in the Location header. A message body suggests updating bookmarks, though modern browsers redirect immediately.
Request
GET /news.html HTTP/1.1
Host: www.example.re
Response
HTTP/1.1 301 Moved Permanently
Location: http://www.example.re/feeds/news.html
Content-Type: text/html; charset=UTF-8
Content-Length: 150
<h1>The Newsfeed has moved</h1>
<body>
The newsfeed has moved permanently to
<a href=/feeds/news.html>here</a>.
Please update your bookmarks.
</body>
Code references
.NET
HttpStatusCode.MovedPermanently
Rust
http::StatusCode::MOVED_PERMANENTLY
Rails
:moved_permanently
Go
http.StatusMovedPermanently
Symfony
Response::HTTP_MOVED_PERMANENTLY
Python3.5+
http.HTTPStatus.MOVED_PERMANENTLY
Java
java.net.HttpURLConnection.HTTP_MOVED_PERM
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_MOVED_PERMANENTLY
Angular
@angular/common/http/HttpStatusCode.MovedPermanently
Takeaway
The 301 Moved Permanently status code indicates the resource has moved to a new location specified in the response. Clients are expected to update their internal data and follow the Location header.
See also
- RFC 9110: HTTP Semantics
- Google: HTTP status codes and network errors
- Soft 404
- 308
- 302
- 307
- Redirects
- HTTP status codes