Broken .htaccess File: How to Find, Fix, and Rebuild It Safely
One character out of place in .htaccess and your entire site can go dark - no warning, no deploy log, nothing. Here's how to find the broken line, fix it, and stop it from happening again.
The symptom
You didn't touch anything - or you did, and now the whole site throws a 500, or the homepage loads but every other page 404s, or WordPress admin works but the front end is blank. Your error log might be completely empty, which is its own clue. On shared cPanel hosting this is almost always .htaccess, and it's worth ruling out first because the fix takes thirty seconds.
Why this file breaks so easily
.htaccess is read by Apache (or interpreted by LiteSpeed, which mimics Apache's syntax) on every single request, before your PHP even runs. There's no build step, no linter, no "are you sure" prompt. A missing closing tag, a smart quote pasted in from a Word doc, or a rule copied from a tutorial written for a different server setup, and Apache refuses to serve the page at all rather than guess what you meant.
It also gets edited by more processes than people realize: WordPress rewrites it when you change permalinks, caching plugins insert their own blocks, security plugins add IP-deny rules, and SSL plugins add HTTPS redirects. Three plugins fighting over the top of the same file is a common way this goes wrong even without anyone touching it by hand.
Step 1: confirm it's actually the file
Don't start guessing at rules - isolate the file first. Over SSH or via File Manager:
cd ~/public_html
mv .htaccess .htaccess_broken
Reload the site. If it comes back immediately, you've confirmed .htaccess was the cause and you can move on to rebuilding it. If the site is still down, put the file back (mv .htaccess_broken .htaccess) and look elsewhere - PHP memory limits, a plugin fatal error, or file permissions are the next suspects.
If you don't have SSH access, do the same thing in cPanel's File Manager: enable "Show Hidden Files" in Settings (top right), find .htaccess in public_html, and rename it.
Step 2: the ways this actually breaks (in order of how often we see them)
1. A mismatched or nested <IfModule> block
Every <IfModule> needs its matching </IfModule>. Copy-pasting a rule from one tutorial into the middle of an existing block - instead of appending it after the closing tag - is the single most common cause we see.
2. Wrong RewriteBase after moving to a subdirectory
If a WordPress or Laravel install lives in /blog instead of the site root, and someone copies a root-level .htaccess without updating RewriteBase, every internal link breaks into 404s while the homepage still loads fine.
3. Smart quotes and invisible characters
Pasting rules from Word, Google Docs, or some blog posts brings along curly quotes (" ") instead of straight ones ("). Apache reads that as a syntax error. It's invisible in most text editors, so this one wastes the most debugging time.
4. Two plugins editing the same block
A caching plugin and a security plugin both insert a # BEGIN ... # END block at the top of the file. If one plugin's update process doesn't clean up properly, you can end up with a stray tag or a half-written block from an interrupted save.
5. LiteSpeed-specific directives on an Apache-only setup (or vice versa)
LiteSpeed Cache adds its own rewrite rules that assume LSCache is running. If a site gets migrated to a plain Apache server without adjusting for that, those directives can cause unexpected behavior - not always a hard crash, but odd caching or redirect loops.
Step 3: rebuild it safely
WordPress - the fastest, cleanest fix. Go to Settings → Permalinks and click Save Changes without changing anything. WordPress detects the missing or renamed file and writes a fresh default one:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Then re-add anything you needed on top (HTTPS redirect, caching plugin rules) one block at a time, testing after each addition.
Non-WordPress apps (Laravel, Magento, plain PHP): restore .htaccess from your last cPanel or JetBackup snapshot rather than rebuilding from memory - these files are usually generated by the framework's installer and hand-recreating every rule correctly is easy to get wrong. If you don't have a backup, your framework's documentation has the canonical default block for its version.
Step 4: verify without trial-and-error reloads
Once you have SSH access, don't just keep editing and refreshing the browser. Check Apache's own syntax test:
apachectl configtest
# or, on some setups:
httpd -t
This won't catch every logical mistake (a working RewriteBase pointed at the wrong folder still "passes"), but it will catch outright syntax errors - unclosed tags, malformed regex - before you reload and take the site down again.
Quick reference
| Symptom | Likely cause | Fix |
|---|---|---|
| Whole site down, blank error log | Syntax error in .htaccess | Rename the file, confirm, rebuild |
| Homepage works, inner pages 404 | Wrong RewriteBase | Match RewriteBase to the actual install path |
| Redirect loop (ERR_TOO_MANY_REDIRECTS) | Conflicting HTTPS/www redirect rules from two plugins | Keep one redirect source, remove the duplicate block |
| Works after backup restore, breaks again after a plugin update | Plugin re-inserting a bad block on activation | Deactivate that plugin, edit its rules manually, reactivate |
Prevention checklist
- Before editing
.htaccessby hand, copy it somewhere safe first -cp .htaccess .htaccess.bak-$(date +%F)takes two seconds. - Edit rules through your app's admin screen (WordPress permalinks, a redirect plugin's UI) instead of by hand whenever that option exists.
- If you must paste rules from a tutorial, paste into a plain text editor first to strip smart quotes before putting them in
.htaccess. - After any plugin that touches rewrite rules is updated, open the file once and eyeball the top few lines.
- Keep at least one recent full backup (cPanel Backup Wizard or JetBackup) so a broken file is a two-minute restore, not a rebuild from scratch.
The file that breaks your whole site is usually the smallest thing to fix - the trick is not guessing at rules but isolating it first. Rename, confirm, rebuild, and you're back up well before you'd have finished reading a forum thread about it.
Frequently asked questions
How do I know if .htaccess is the cause and not something else?
Rename it (mv .htaccess .htaccess_broken) and reload the site. If the site comes back immediately, .htaccess was the problem. If it's still down, restore the original filename and look at PHP memory limits or a plugin conflict instead.
Will renaming .htaccess delete my rewrite rules?
No, renaming just disables the file temporarily so Apache stops reading it - nothing inside is deleted. Once you confirm it's the cause, you can rebuild a clean version and copy back any custom rules you still need.
I don't have SSH access - can I still fix this?
Yes. In cPanel, open File Manager, turn on "Show Hidden Files" under Settings, then find and rename .htaccess inside public_html the same way you would over SSH.
Why did .htaccess break after a plugin update, when I didn't touch it?
Caching, security, and SEO plugins all insert their own rule blocks into .htaccess. If an update writes a block incorrectly or two plugins' blocks conflict, the file can end up broken without you editing it directly.
Is this the same thing as a redirect loop error?
Not always, but redirect loops are one common symptom of a broken .htaccess - usually from two plugins each adding their own HTTPS or www redirect rule and looping against each other. Removing the duplicate block fixes it.