How do you use this tool?
- Paste the contents of your `.htaccess` or pick the file. The check runs as you type, there is no start button.
- Under „Line by line“ every directive gets a sentence in plain language. Coloured borders mark the lines with findings.
- Under „Test a URL“ you enter a path and see which rules fire in order and where the request ends up.
- The two switches for file and directory answer the `-f` and `-d` conditions. Without them there is no way to decide whether a rule applies.
- Under „Redirect chain“ you see how many hops an address takes and whether it ends up back at itself.
What does the .htaccess checker do?
It reads a file you already have and answers three questions a generator cannot: what does this line do, what is wrong with it, and what happens to this address.
The difference from the common testers is direction. Most of them take a URL plus a few rules and show what comes out. That helps when you wrote the rules yourself. Someone who inherited a grown file has a different problem: they do not know what is in there, so they do not dare delete anything. That is why every directive here carries a sentence in ordinary language.
On top of that comes a rating of how hard a line is to take back. Switching off directory listing is reversible at any time. An HSTS header with preload keeps acting in every browser that saw it once, no matter what the server sends afterwards, and getting off the preload list takes months. In a text file both look the same. In the output they do not.
Why does the server answer 500 after the upload?
That is by far the most common way to take a site offline with an .htaccess, and the cause is nearly always the same: a directive whose module is not loaded.
You would expect Apache to read past an unknown line. It does not. It aborts the request, for the whole site, not only for the rule in question. The error log then reads Invalid command 'Order', perhaps misspelled or defined by a module not included in the server configuration.
Two groups stand out. The first is the old access control from Apache 2.2: Order, Allow from, Deny from, Satisfy. The Apache upgrading guide has named Require as the replacement since 2012, but the old lines survive in tutorials, forum answers and the default snippets of some plugins. The second group needs a module that cheap plans often skip: Header needs mod_headers, ExpiresDefault needs mod_expires, RewriteRule needs mod_rewrite.
The way out is the same in both cases. An <IfModule mod_headers.c> around the block turns the abort into a silent skip. The rule then has no effect, but the site stays up, and the missing header tells you where to look.
How do I spot an infinite redirect?
By two rules feeding each other. The best known case does not even need two lines in your own file.
A rule such as RewriteRule ^(.+)/$ /$1 [R=301,L] removes the trailing slash. For /blog/ it sends the visitor to /blog. If blog is a real directory, mod_dir takes over, which ships with DirectorySlash On, and puts the slash back. The browser follows, the rule fires again, and after roughly twenty hops it gives up with ERR_TOO_MANY_REDIRECTS. That whole section of the site is unreachable.
The missing line is RewriteCond %{REQUEST_FILENAME} !-d directly above the rule. It excludes real directories, which is exactly the set mod_dir claims for itself.
The checker reports this rule as an error, and the redirect-chain tab lets you reproduce it: enter the path, tick „exists as a directory“, and the chain shows the hop.
Which rule fires for a given address?
That is what the URL test is for. You enter a path, and the tool walks the rules in order the way Apache would, showing every one that matches together with its line number.
Two details there matter more than they look. First the leading slash: inside an .htaccess Apache matches the pattern against the path with the first slash already stripped. A rule copied from a server config with ^/blog$ therefore never matches, and people look for the mistake somewhere else for a long time. The test reproduces this.
Second, the two switches for file and directory. Conditions such as %{REQUEST_FILENAME} !-f query the server’s file system, which a browser cannot see. Rather than guess, the tool asks you. That makes exactly the rules decidable that most tutorials hang on.
Where a condition genuinely cannot be evaluated, because it depends on a cookie or branches with [OR], the rule is not applied and the line is listed as „not evaluated“. The result is therefore a lower bound: the server may apply more, but what is shown applies there too.
What does a redirect chain cost?
Load time, and a little ranking. Every hop is its own request with its own latency; on a slow mobile connection three hops are clearly noticeable.
Chains are rarely built on purpose. They grow when HTTPS enforcement, www canonicalisation and an old single redirect end up in the same file. Each rule is correct on its own; together they turn http://www.example.com/old into https://www.example.com/old into https://example.com/old into https://example.com/new. Three hops where one would do.
The third tab walks the chain your own file produces and counts the hops. If an address ends up back at itself, that shows as a loop rather than as a working redirect.
Which lines can the tool not evaluate?
Everything outside the part that turns up in real files. Evaluated are rewrites with their conditions and flags, redirects via Redirect and RedirectMatch, headers, the access directives of both Apache generations, caching, compression, error documents, directory options and password protection.
When something else appears, a note next to it says the line was not evaluated. It stays in the listing unchanged. That is deliberate: a check that quietly skips unknown lines ends up issuing an all-clear it cannot back.
One limitation concerns ordering. Apache runs mod_alias and mod_rewrite in separate phases, so Redirect and RewriteRule do not simply run top to bottom. Here they are evaluated in file order, because that is the order a person reads the file in. If a file mixes both, the real order can differ, and that is stated under the result.
How does the checker relate to the generator?
They are the two directions of the same thing. The .htaccess generator builds a file from a rule picker and takes care of module guards, the Apache version and the ordering. The checker takes a finished file and explains it.
In practice you usually go there and back once: read the inherited file here, note the rules that are genuinely needed, and set them up cleanly in the generator. What falls away are the lines that have been copied along for years and no longer do anything.
If you are moving servers, the translation into nginx syntax lives in the nginx config generator. For the password file that AuthUserFile points at, there is the .htpasswd generator.
Background on the file itself is in the Apache .htaccess howto and in the Wikipedia article.
Last updated: