301

HTTP 301 Moved Permanently

3xx Redirection

3xx Redirection RFC 7231, Section 6.4.2

What is HTTP 301 Moved Permanently?

The 301 (Moved Permanently) status code indicates that the target resource has been assigned a new permanent URI. The user agent should automatically redirect to the new URI and update bookmarks and links. Search engines will transfer SEO value from the old URL to the new URL. This is a critical redirect for website restructuring and domain changes.

Common Use Cases

  • Domain migration (changing domain name)
  • Enforcing HTTPS (redirecting HTTP to HTTPS)
  • URL restructuring and permalink changes
  • Canonical URL redirect for SEO

Usage Example

When changing your domain from old-domain.com to new-domain.com, set up 301 redirects from every old URL to its corresponding new URL. Search engines will transfer page rank to the new URLs, and browsers will automatically update bookmarks. This is also used to redirect HTTP to HTTPS.

# Nginx - permanent redirect from HTTP to HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

# Laravel redirect
return redirect('https://new-domain.com/users', 301);

Common Mistakes

⚠️

Mistake: Using 301 for temporary redirects like post-login or A/B testing

Fix: Use 302 Found or 307 Temporary Redirect for non-permanent redirects. Search engines cache 301 redirects permanently, which can cause issues if you need to change the redirect target later.

⚠️

Mistake: Forgetting to update the Location header with the full absolute URL

Fix: The Location header in a 301 response must be an absolute URL (including scheme and host). Relative URLs are not allowed and may cause unexpected behavior.

⚠️

Mistake: Redirecting all 404s to the homepage with a 301

Fix: Do not use 301 redirects for missing pages. If a page is genuinely gone, return 404 or 410 Gone. Using 301 for all errors confuses search engines and dilutes SEO value.

Last updated: 21 Jun 2026