Error fix · Server errors

Apache .htaccess 500 Internal Server Error: Find the Bad Line

A broken .htaccess file makes Apache return 500 for the whole site. Read the error log, find the bad directive, and fix syntax, modules or AllowOverride.

Error message500 Internal Server Error .htaccess

By SiteDownCheck Editorial · Updated October 21, 2026 · 4 min read

If your site went from working to a plain "500 Internal Server Error" right after you edited .htaccess, installed a plugin or changed hosting, the file is almost certainly the cause. Apache reads .htaccess on every request, so a single bad line breaks every URL under that directory at once, including the home page.

The browser will not tell you why. The Apache error log will, and it usually names the exact file, line and directive. For the general picture of 500 errors, see Fix 500 Internal Server Error; this page is only about .htaccess.

Step 1: confirm .htaccess is the cause

Rename the file and reload the page:

mv .htaccess .htaccess.off
curl -I https://example.com/

If the status changes from 500 to 200 (or to a 404 on pretty URLs), you have your answer. Keep the old file as .htaccess.off so you can inspect it. On shared hosting without a shell, rename it in the file manager. Confirm the result with the HTTP Status Checker.

Step 2: read the error log

Typical locations are /var/log/apache2/error.log on Debian and Ubuntu, /var/log/httpd/error_log on RHEL-family systems, and a per-account error_log on many control panels.

sudo tail -n 30 /var/log/apache2/error.log

The entries you want look like these:

/var/www/html/.htaccess: Invalid command 'php_value', perhaps misspelled or defined by a module not included in the server configuration
/var/www/html/.htaccess: RewriteCond: bad flag delimiters
/var/www/html/.htaccess: Options not allowed here
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary.

Match your line to one of the causes below.

Common causes

Invalid command

The directive belongs to a module that is not loaded, or it is misspelled. This is the most common case, and it has its own page: Apache Invalid command in .htaccess.

Syntax error in a directive

Typical mistakes are an unclosed <IfModule>, a missing space before a flag list, or smart quotes pasted from a blog post.

  # Wrong: no space before the flags
RewriteRule ^old$ /new[R=301,L]

  # Right
RewriteRule ^old$ /new [R=301,L]

Check the file for non-ASCII quotes with grep -nP '[^\x00-\x7F]' .htaccess.

The directive is not allowed in .htaccess

The AllowOverride setting of the parent Directory block decides what an .htaccess file may contain. If it is None or lists only some groups, a directive from another group raises "not allowed here". Server-level settings such as ServerName, Listen or <VirtualHost> never work in .htaccess. On a server you control:

<Directory /var/www/html>
    AllowOverride All
</Directory>

Use AllowOverride All only where you trust the content, and use narrower groups (FileInfo Indexes Options=...) where you can.

If the log says Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden, add this at the top of the file:

Options +FollowSymLinks

PHP settings that do not apply

php_value and php_flag only work when PHP runs as an Apache module (mod_php). Under PHP-FPM or CGI they cause a 500. Move those settings to .user.ini or php.ini instead.

Redirect loop

"Request exceeded the limit of 10 internal redirects" means a rewrite rule matches its own output. The usual fix is a condition that excludes the target, for example RewriteCond %{REQUEST_URI} !^/index\.php. For browser-side loops, see ERR_TOO_MANY_REDIRECTS.

File permissions

An .htaccess that Apache cannot read can also produce a 500 or 403. Typical safe values are 644 for the file and 755 for directories, with the owner your deploy user.

Step 3: validate before you reload

If you have shell access and the rules live in a vhost rather than .htaccess, test the config before applying it:

sudo apachectl configtest

This does not parse .htaccess files, because those are read per request. That is why a bad .htaccess fails live. Prefer putting rules in the virtual host config when you can (with AllowOverride None), which is both safer and faster.

Step 4: bisect

For a long file, comment out half of it, reload, and repeat. A few minutes of halving finds the offending line, especially in files appended to by several plugins.

How to verify

After the fix, request a few URL types and compare status codes: the home page, a pretty URL, a static file and a 404 path. The HTTP Header Checker shows the final status and headers, and the Redirect Checker confirms any rewrite rules still redirect as intended. Put an Uptime Monitor on the home page so the next bad edit alerts you quickly.

Next steps

FAQ

Why does my whole site break from one .htaccess line?

Apache parses the file on every request to that directory tree, and a configuration error aborts the request with 500. Every URL below the file is affected.

Where is the Apache error log?

Usually /var/log/apache2/error.log on Debian-based systems and /var/log/httpd/error_log on RHEL-family systems. Hosting panels often show a per-site log in the control panel.

Can I test .htaccess changes safely?

Edit a copy, keep the working version beside it, and test with curl -I. Making changes during low traffic and keeping a one-command rollback is the practical safety net.

Does the nginx server read .htaccess?

No. nginx ignores .htaccess entirely, so rules must be rewritten as nginx config.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

This page is general information written by our editorial team and updated when documentation changes. Servers and providers differ, so test changes safely first. See our editorial policy and disclaimer.