Apache .htaccess Redirect Loop 500 Internal Server Error on Ubuntu 22.04 LTS
Fix Apache .htaccess redirect loop causing a 500 Internal Server Error on Ubuntu 22.04 LTS. Diagnose misconfigurations, mod_rewrite issues, and permissions for stable web hosting.
Fix Apache .htaccess redirect loop causing a 500 Internal Server Error on Ubuntu 22.04 LTS. Diagnose misconfigurations, mod_rewrite issues, and permissions for stable web hosting.
When your Apache web server throws a 500 Internal Server Error due to an .htaccess redirect loop on Ubuntu 22.04 LTS, it indicates a critical misconfiguration preventing your website from serving content. This guide provides a highly technical, step-by-step approach to diagnose and resolve such issues, ensuring your web applications remain accessible and performant. As experienced SysAdmins, we know these issues often stem from subtle errors in mod_rewrite rules or improper server configurations.
Symptom & Error Signature
Users attempting to access your website will typically encounter one of the following:
- A blank page with the text "500 Internal Server Error".
- A browser error indicating "ERR_TOO_MANY_REDIRECTS" or similar, which eventually might lead to a
500if the server exhausts resources or hits a recursion limit.
Crucially, the server's error logs will provide more specific details. You can usually find these logs at /var/log/apache2/error.log on Ubuntu systems.
Typical Apache error.log entries for this issue:
[Tue Nov 03 10:30:00.123456 2026] [core:alert] [pid 12345:tid 140000000000000] [client 192.168.1.100:54321] /var/www/html/.htaccess: RewriteRule: bad flag delimiters
[Tue Nov 03 10:30:01.654321 2026] [mod_rewrite:error] [pid 12346:tid 140000000000000] [client 192.168.1.101:54322] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
[Tue Nov 03 10:30:02.987654 2026] [mod_rewrite:error] [pid 12347:tid 140000000000000] [client 192.168.1.102:54323] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Last rule tried: # HTTP to HTTPS
[Tue Nov 03 10:30:03.111222 2026] [authz_core:error] [pid 12348:tid 140000000000000] [client 192.168.1.103:54324] AH01630: client denied by server configuration: /var/www/html/.htaccess
Root Cause Analysis
A 500 Internal Server Error triggered by an .htaccess redirect loop on Apache is almost always a direct consequence of mod_rewrite directives that are either syntactically incorrect, logically flawed, or encountering server-level permission/configuration restrictions. Common underlying causes include:
- Misconfigured
RewriteRules: The most frequent culprit. Rules are defined in a way that causes an infinite redirection chain (e.g., redirectinghttp://example.comtohttps://example.combut applying the rule even when the request is alreadyhttps, orwwwto non-wwwwithout proper conditions). - Incorrect
RewriteBase: If your application resides in a subdirectory, an improperly set or missingRewriteBasecan lead to repeated path rewrites. - Missing or Incorrect
RewriteCond:RewriteConddirectives are crucial for defining the conditions under which aRewriteRuleshould apply. Without them, a rule might repeatedly apply to its own rewritten output. AllowOverride Nonein Apache Configuration: If the main Apache configuration (e.g.,apache2.confor aVirtualHostfile) hasAllowOverride Nonefor the directory containing the.htaccessfile, Apache will completely ignore the.htaccessdirectives, which can lead to unexpected behavior or500errors if a required rewrite isn't happening.mod_rewriteModule Not Enabled: If themod_rewritemodule is not loaded and enabled in Apache, anyRewriteRuleorRewriteConddirectives in.htaccesswill result in a500 Internal Server Errorbecause Apache doesn't understand the syntax.- Syntactic Errors in
.htaccess: Even a simple typo, missing space, or incorrect flag delimiter ([R=301,L]) can cause a500error as Apache fails to parse the file. - File Permissions or Ownership: Incorrect file permissions (e.g., not readable by the
www-datauser) or ownership for the.htaccessfile can prevent Apache from processing it, leading to a500error. - Server-Level vs.
.htaccessConflicts: Sometimes, aVirtualHostconfiguration might already handle redirects or URL rewriting, and conflicting rules in.htaccesscan create a loop.
Step-by-Step Resolution
Follow these steps meticulously to diagnose and resolve your Apache .htaccess redirect loop and 500 Internal Server Error.
1. Temporarily Disable the .htaccess File
The quickest way to confirm if .htaccess is the source of the problem is to temporarily disable it.
cd /var/www/html/your_domain_root/ # Navigate to your web root
sudo mv .htaccess .htaccess.bak # Rename the file
After renaming, try accessing your website. If the 500 Internal Server Error disappears (you might see a different error or the site loads partially), you've confirmed .htaccess is the culprit.
2. Check Apache Error Logs
Even after disabling, review the logs for any previous errors and to ensure Apache restarts cleanly.
sudo tail -f /var/log/apache2/error.log
Look for lines containing RewriteRule, AH00124, bad flag delimiters, or configuration error. This provides crucial clues.
3. Verify mod_rewrite Module Status
If mod_rewrite is not enabled, any RewriteRule will cause a 500 error.
sudo a2enmod rewrite # Enable the rewrite module
sudo systemctl restart apache2 # Restart Apache to apply changes
Check the module status:
apache2ctl -M | grep rewrite
You should see rewrite_module (shared) in the output.
4. Examine Apache VirtualHost/Directory Configuration
Apache must be configured to allow .htaccess overrides. By default, AllowOverride None is often set for security.
Locate your VirtualHost file: For most installations, this is in
/etc/apache2/sites-available/your_domain.conf.sudo nano /etc/apache2/sites-available/your_domain.confEnsure
AllowOverride All: Inside the<VirtualHost>block, locate the<Directory>directive corresponding to your web root (/var/www/html/your_domain_root/for example). ChangeAllowOverride NonetoAllowOverride All.<VirtualHost *:80> ServerAdmin webmaster@localhost ServerName yourdomain.com ServerAlias www.yourdomain.com DocumentRoot /var/www/html/your_domain_root ErrorLog ${APACHE_LOG_DIR}/your_domain_error.log CustomLog ${APACHE_LOG_DIR}/your_domain_access.log combined <Directory /var/www/html/your_domain_root> Options Indexes FollowSymLinks MultiViews AllowOverride All # THIS MUST BE ALL FOR .htaccess to work Require all granted </Directory> </VirtualHost> # Repeat for HTTPS VirtualHost if applicable <VirtualHost *:443> ServerName yourdomain.com ServerAlias www.yourdomain.com DocumentRoot /var/www/html/your_domain_root <Directory /var/www/html/your_domain_root> Options Indexes FollowSymLinks MultiViews AllowOverride All # AND HERE! Require all granted </Directory> # ... SSL configuration ... </VirtualHost>Setting
AllowOverride Allallows.htaccessfiles to override almost all configuration directives. Use this judiciously; for production, consider more granularAllowOverrideoptions if specific directives are not needed.Test and Restart Apache:
sudo apache2ctl configtest # Test configuration syntax sudo systemctl restart apache2 # Restart Apache
5. Debugging .htaccess RewriteRules
If the problem persists after verifying mod_rewrite and AllowOverride, the issue is almost certainly within the RewriteRules themselves. Re-enable your .htaccess (sudo mv .htaccess.bak .htaccess) and proceed.
Isolate the Problematic Rule: Comment out (prefix with
#) allRewriteRuleandRewriteConddirectives exceptRewriteEngine On. Then, uncomment them one by one, testing the site after each change, until the500error reappears. This helps pinpoint the exact rule causing the loop.Common Redirect Loop Scenarios and Fixes:
HTTP to HTTPS Redirect Loop: A common mistake is redirecting to HTTPS without checking if the connection is already HTTPS.
Incorrect (causes loop):
RewriteEngine On RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]Correct:
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]The
RewriteCond %{HTTPS} offensures the rule only applies if the connection is not HTTPS.WWW to Non-WWW (or vice-versa) Redirect Loop: Similar to HTTPS, failing to check the
HTTP_HOSTbefore redirecting can cause a loop.Incorrect (causes loop):
RewriteEngine On # To non-WWW RewriteRule ^(.*)$ http://yourdomain.com/$1 [L,R=301]Correct (Non-WWW to WWW):
RewriteEngine On RewriteCond %{HTTP_HOST} ^yourdomain.com [NC] RewriteRule ^(.*)$ http://www.yourdomain.com%{REQUEST_URI} [L,R=301]Correct (WWW to Non-WWW):
RewriteEngine On RewriteCond %{HTTP_HOST} ^www.yourdomain.com [NC] RewriteRule ^(.*)$ http://yourdomain.com%{REQUEST_URI} [L,R=301]Trailing Slash Issues: Redirecting to add/remove a trailing slash without proper conditions.
Example (Add trailing slash):
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !(.[a-zA-Z0-9]{1,5}|/)$ RewriteRule ^(.*)$ /$1/ [R=301,L]Ensure your application doesn't internally rewrite paths to remove the trailing slash, causing a conflict.
Increase
RewriteLogLevel(Debuggingmod_rewrite): For Apache 2.4+, you can increaseRewriteLogLevelwithin your VirtualHost or main Apache configuration (NOT in.htaccessfor security and performance reasons) to get extremely detailed debugging output inerror.log.# In /etc/apache2/sites-available/your_domain.conf or apache2.conf <VirtualHost *:80> # ... other configurations ... RewriteEngine On RewriteOptions Inherit RewriteLogLevel 3 # Set to 3 for moderate detail, 9 for maximum detail (very verbose!) RewriteLog ${APACHE_LOG_DIR}/rewrite.log # Optional: dedicated log for rewrites </VirtualHost>Using
RewriteLogLevellevels 3-9 generates a significant amount of log data and can severely impact server performance. Only enable this temporarily for debugging and set it back to0or comment it out once done. Be mindful of sensitive data possibly appearing in logs at higher levels.After setting
RewriteLogLevel, restart Apache:sudo systemctl restart apache2Now, check
/var/log/apache2/error.log(orrewrite.logif specified) and you'll see every step of themod_rewriteprocess, helping you trace where the loop occurs.
6. Check File Permissions and Ownership
Incorrect permissions can prevent Apache from even reading the .htaccess file, leading to a 500 error.
Check current permissions:
ls -la /var/www/html/your_domain_root/.htaccessOutput example:
-rw-r--r-- 1 root root 243 Nov 3 10:00 .htaccessSet correct permissions and ownership: The
.htaccessfile should typically be owned by the web server user (e.g.,www-dataon Ubuntu) or at least be readable by it. Permissions usually644or640are safe.sudo chown www-data:www-data /var/www/html/your_domain_root/.htaccess sudo chmod 644 /var/www/html/your_domain_root/.htaccessNever set
.htaccessfile permissions to777. This is a significant security risk and is completely unnecessary for Apache to read the file.644(readable by owner, group, and others) or640(readable by owner and group) is standard and secure.
7. Clear Browser Cache
After making any changes, always clear your browser's cache or use an incognito/private browsing window to ensure you're not seeing a cached redirect.
Browsers aggressively cache 301 (Permanent) redirects. If you tested a faulty rule and it was cached, even fixing the server won't show immediate results without clearing the cache.
By systematically following these steps, you should be able to pinpoint and rectify the misconfiguration causing the Apache .htaccess redirect loop 500 Internal Server Error on your Ubuntu 22.04 LTS server. Remember to always test changes in a staging environment first if possible, and to back up configuration files before modification.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.