Updated: 8 October 2026 · Applies to: Apache HTTP Server 2.4 (tested on 2.4.69, 2.4.66 on Ubuntu 26.04 and 2.4.63 on AlmaLinux 10)
To make a permanent (301) redirect in Apache, add one line to the site’s virtual host or .htaccess file: Redirect permanent "/old-page.html" "https://www.example.com/new-page/". RedirectPermanent "/old-page.html" "https://www.example.com/new-page/" and Redirect 301 ... do exactly the same. These directives come from mod_alias, which is loaded by default. Without permanent or 301, Redirect sends a temporary 302.
1. Redirect permanent and RedirectPermanent
All three lines below send a 301:
Redirect permanent "/old-page.html" "https://www.example.com/new-page/" RedirectPermanent "/docs" "/manual" Redirect 301 "/old.html" "/new.html"
What we got with curl -I:
/old-page.html HTTP/1.1 301 Moved Permanently Location: https://www.example.com/new-page/ /docs/install.html?lang=en HTTP/1.1 301 Moved Permanently Location: http://localhost/manual/install.html?lang=en /old.html?x=1 HTTP/1.1 301 Moved Permanently Location: http://localhost/new.html?x=1 /docsfoo HTTP/1.1 404 Not Found
Things to know:
- The old path must start with
/and is case-sensitive. - It matches the start of the path, and anything after it is added to the new URL, together with the query string.
/docsalso redirected/docs/install.html. - Only whole path segments match, so
/docsdid not catch/docsfoo. - A target that starts with
/stays on the same site; Apache turns it into a full URL. - Other status words:
temp(302, the default),seeother(303) andgone(410, with no target:Redirect gone "/removed.html"). For the difference between 301 and 302, see what is a 302 redirect.
2. Move a whole site to a new domain
In the virtual host of the old domain only:
<VirtualHost *:80>
ServerName old.example
ServerAlias www.old.example
Redirect permanent "/" "https://new.example/"
</VirtualHost>
Every path is kept: /any/path.html went to https://new.example/any/path.html. If you have an HTTPS virtual host for the old domain, add the same line there.
3. RedirectMatch: patterns with regular expressions
RedirectMatch 301 "^/blog/(.*)$" "https://blog.example.com/$1"
/blog/2026/hello-world went to https://blog.example.com/2026/hello-world. Anchor the pattern with ^: without it, RedirectMatch matches anywhere in the path, and /archive/blog/post was redirected as well.
4. RewriteRule with [R=301]: redirects with conditions
Use mod_rewrite when the redirect depends on something other than the path, such as the host name or HTTPS. The Apache manual recommends Redirect and RedirectMatch for simple cases.
RewriteEngine On
# www to non-www, and HTTP to HTTPS
RewriteCond "%{HTTP_HOST}" "^www\.(.+)$" [NC]
RewriteRule "^" "https://%1%{REQUEST_URI}" [R=301,L]
RewriteCond "%{HTTPS}" "!=on"
RewriteRule "^" "https://%{HTTP_HOST}%{REQUEST_URI}" [R=301,L]
# old domain to new domain (in a virtual host)
RewriteCond "%{HTTP_HOST}" "^(www\.)?old\.example$" [NC]
RewriteRule "^(.*)$" "https://new.example$1" [R=301,L]
R=301makes it permanent. A plain[R]gave a 302 in our test, andR=308gave308 Permanent Redirect.- In a virtual host, the matched path starts with a slash, so write
https://new.example$1. Withhttps://new.example/$1we gotLocation: https://new.example//page. - In
.htaccess, the path is relative to that folder and has no leading slash, so/$1is correct there. - If a
Redirectand aRewriteRulein the same virtual host match the same URL, theRewriteRulewon in our test. Use one method per URL.
More on rules and flags: how to use Apache mod_rewrite. HTTPS only: permanent redirect to HTTPS with .htaccess.
5. Virtual host or .htaccess?
The virtual host is faster and always works. .htaccess is read only if the folder allows it with AllowOverride FileInfo (or All). Ubuntu (/var/www) and AlmaLinux (/var/www/html) ship with AllowOverride None. In our tests:
- With
AllowOverride None, the.htaccessfile was ignored and the old URL returned 404. - With only
AllowOverride AuthConfig, the request failed with 500 and the error log showed.htaccess: Redirect not allowed here.
In .htaccess, Redirect still uses the full path from the site root, for example Redirect 301 "/sub/a.html" "/sub/b.html". On cPanel hosting you can also use the Redirects tool: redirect a website in cPanel.
6. Enable the module and apply the change
Ubuntu and Debian: mod_alias is on; mod_rewrite is not.
sudo a2enmod rewrite sudo apache2ctl configtest sudo systemctl restart apache2
AlmaLinux, Rocky Linux and RHEL: both modules are loaded by default (/etc/httpd/conf.modules.d/00-base.conf).
sudo apachectl configtest sudo systemctl reload httpd
Always run the config test first. Typical errors:
Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration:mod_rewriteis not enabled.RedirectPermanent takes two arguments, a document to be redirected, then the destination URL: the target URL is missing.
7. Test the redirect
curl -I http://www.example.com/old-page.html
Look for 301 Moved Permanently and the Location header. curl shows the server’s real answer, without a browser’s history or cache in the way. To follow a chain of redirects to the end, use curl -IL.
Official documentation: mod_alias (Redirect, RedirectMatch, RedirectPermanent), RewriteRule flags and when not to use mod_rewrite.