You open your site and the page is blank. Or worse: the browser says 500 Internal Server Error and no log says anything either. In nine out of ten cases where I've seen this sign, the .htaccess file in the root of public_html was the culprit; an extra line, a wrong space, or a rule that didn't come after RewriteEngine On. This guide covers exactly the things you run into during real debugging.
What htaccess is and why the order of its lines matters
The .htaccess file is a simple text file that the Apache or LiteSpeed web server reads on every request and executes before reaching PHP. That means every line you write in it affects every visit. This very feature is what makes a single wrong line take the whole site offline.
Execution order is top to bottom, and the first rule that matches wins. If you write a general redirect before an exception, the exception will never run. I see this a lot in practice: someone wants everything to go to HTTPS, but hasn't excluded the robots.txt file or the /.well-known/acme-challenge/ path, and then automatic SSL renewal fails.
Correct order of blocks
- Basic settings:
Options -Indexes, default encoding - Forced redirects (HTTPS, removing www or adding it)
- WordPress or framework rewrite rules
- Protecting files and folders
- Headers and caching
Write the 301 redirect correctly
The most common task is moving all traffic to the HTTPS version and a single domain. Put this block at the top of the file:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
A point many people miss: the [OR] flag only works between two consecutive RewriteCond lines, not between three. If you add a third condition, the logic changes and the redirect becomes a loop. The sign is also obvious: the browser says ERR_TOO_MANY_REDIRECTS and the site won't come up.
To redirect a specific page, using Redirect is simpler than rewriting:
Redirect 301 /old-page.html https://www.example.com/new-page/
This line only works for the exact path and has no effect on subpaths. If you want an entire folder moved, write RedirectMatch 301 ^/old-folder/(.*)$ /new-folder/$1. If you're changing the site's domain entirely, before anything else read the guide to changing domain without losing SEO; a wrong redirect at this stage can destroy years of rankings.
Protecting sensitive folders and files
The wp-config.php file, the wp-includes folder, and backup files like .sql or .zip should not be accessible from outside. Put this block in the root:
<Files wp-config.php>
Require all denied
</Files>
<FilesMatch "\.(sql|bak|log|env)$">
Require all denied
</FilesMatch>
On Apache version 2.2, the Require all denied directive is not supported and you must write Order allow,deny and Deny from all. If your server has Apache 2.4 or higher (which almost everywhere does), the same Require is correct. Confusing these two gives a 500 error with no explanation.
To password-protect a folder, first create the password file:
htpasswd -c /home/user/.htpasswd admin
Then in the .htaccess of that same folder:
AuthType Basic
AuthName "Restricted"
AuthUserFile /home/user/.htpasswd
Require valid-user
The AuthUserFile path must be absolute. A relative path is one of the most frequent mistakes, and the result is a 500 error, not a "wrong password" message.
Custom error page and headers
The server's default 404 page gives the user a bad experience. Create a 404.html file and add this line:
ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
The path must be relative to the domain root, not to the file. If you write ErrorDocument 404 404.html (without the leading slash), Apache returns it as plain text and the user sees a single line of text.
For security and cache headers, the mod_headers module is required:
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
<FilesMatch "\.(css|js|jpg|png|webp|woff2)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
</IfModule>
The number 2592000 equals 30 days. For static files this number is reasonable, but for index.html or anything that might change, a one-month cache means the user sees the old version for up to a month. This is where people make mistakes: someone changes the site's styles, refreshes the site, doesn't see the change, and thinks it wasn't uploaded. In reality, it's the browser cache.
500 error: where to look
When the site gives a 500, the first thing to do is temporarily disable the file:
mv .htaccess .htaccess.bak
If the site comes up, the problem is definitely in that file. Now restore it line by line or comment out from the end. Three common causes:
- A directive whose module isn't installed on the server, like
php_valueon servers that run PHP with FastCGI - A space or invisible character (such as a BOM) at the beginning of the file saved with a Windows editor
- A rule that isn't wrapped in
<IfModule>and whose module is disabled
Take the second case seriously. Check the file with file .htaccess; if you see UTF-8 Unicode (with BOM), remove the BOM. This one extra byte takes the whole site down and you won't see anything special in the log either.
If the error is in WordPress and you get a blank page rather than a 500, the troubleshooting path is different; the guide to fixing the white screen in WordPress and PHP covers this step by step.
htaccess and hosting resource limits
A point that's less often mentioned: .htaccess is read on every request, and if you have dozens of heavy rules, it affects response time. On shared hosting where resources are divided among several sites, this effect is more noticeable. If you see the site has become slow and you've just added htaccess rules, first understand the concept of Entry Process and how it differs from visits; the slowness problem may be coming from somewhere else.
In practice, most sites need fewer than 30 lines of htaccess. If your file has passed 200 lines, part of the work probably needs to be done at the server level or in the application code. On Linux hosting you can manage rules at the domain level, but if traffic and the need for global settings have exceeded what shared hosting offers, a dedicated server is the more logical option, because there you write the settings once in httpd.conf, not in every folder.
Before saving, do these things
Always keep a backup of the healthy file. Before any change, run cp .htaccess .htaccess.backup. If you have FTP, the guide to managing FTP accounts shows how to download and upload the file without hassle. To test redirects, use the browser's incognito mode, because a 301 cache in a normal browser is almost impossible to clear and will mislead you.
And if you're not sure the domain correctly points to the server or the problem is DNS, before touching htaccess check the DNS and network lookup tool once. Half the cases reported as an "htaccess problem" are actually a wrong A record.
Frequently asked questions
Why does the site give a 500 error after changing htaccess?
It's almost always one of these three causes: a directive whose module isn't enabled on the server, a BOM character at the beginning of the file, or a syntax error such as a missing </IfModule>. Temporarily set the file aside with mv .htaccess .htaccess.bak; if the site comes up, the problem is definitely in that file.
What's the difference between Redirect and RewriteRule in htaccess?
Redirect is for fixed and simple paths and has no effect on subpaths. RewriteRule combines with RewriteCond and supports complex conditions like protocol, domain, or browser type. Use the former for redirecting a single page and the latter for conditional logic.
Does htaccess work on Nginx?
No. Nginx doesn't read the htaccess file and rules must be written in the server block of the config file. If you're on hosting whose web server is Nginx, you must ask the panel or the support team to apply the rules at the server level.
How do I know if htaccess is causing the site to slow down?
Temporarily disable the file and compare response time with a speed measurement tool. If the difference is noticeable, remove duplicate rules or heavy conditions. In most cases, htaccess's effect on speed is negligible and the slowness comes from plugins or database queries.