Apache Linter — .htaccess & httpd.conf Checker Online
Paste your Apache config and catch directive typos, invalid RewriteRule flags, unbalanced blocks, wrong-context directives, and risky settings — before they 500 your site. Free, no signup, runs 100% in your browser.
Lint Apache config
30 heuristic rules across error / warning / info, with exact line numbers. Click any issue to jump to its line.
apachectl configtest. It does not know which modules are loaded on your server — module requirements are flagged as info notes ("may need mod_rewrite"), not verdicts. Always run apachectl configtest on the server before deploying.Rule reference
Every rule the linter can report, with its severity.
| Rule | Severity | What it catches |
|---|---|---|
unknown-directive | error | Directive not in the ~120-entry dictionary; suggests the closest match (e.g. RewriteEngin → RewriteEngine). |
unknown-block | error | Unknown <...> container tag. |
unclosed-block | error | Block opened but never closed before end of file, with the opening line number. |
stray-close | error | Closing tag with no matching opening tag. |
block-mismatch | error | Closing tag does not match the innermost open block; auto-recovers and keeps linting. |
stray-else | error | <Else>/<ElseIf> without a matching <If>. |
block-arg | warning | Container missing its argument (e.g. bare <IfModule>). |
wrong-context | error | Directive used where Apache forbids it (e.g. ServerName in .htaccess). |
allowoverride-ctx | error | AllowOverride outside a <Directory> section. |
ctx-block | error | Block not allowed here (<VirtualHost>/<Directory> in .htaccess; nested <VirtualHost>). |
rewrite-flag | error | Invalid RewriteRule flag (flags are case-sensitive), flag missing its required value, bad R= code, or unclosed [...]. |
rewritecond-flag | error | Invalid RewriteCond flag — only NC, OR, NV exist. |
rewriterule-args / rewritecond-args | error | RewriteRule/RewriteCond with too few arguments. |
no-rewriteengine | warning | Rewrite directive before any RewriteEngine On — the rule would be silently ignored. |
orphan-rewritecond | warning | RewriteCond not followed by a RewriteRule/RewriteCond — a condition with no rule does nothing. |
rewritebase-ctx | warning | RewriteBase in server/virtualhost context, where it is ignored. |
redirect-code | error | Invalid Redirect status — use 301, 302, 303, 307, 308 (or permanent/temp/seeother/gone). |
redirect-args | error | Redirect missing its source or target. |
redirect-overlap | warning | Redirect and RewriteRule targeting the same literal path (mod_alias runs first). |
deprecated-22 | warning | Apache 2.2 Order/Allow/Deny/Satisfy — prefer Require on 2.4. |
mixed-auth | warning | Mixing 2.4 Require with 2.2 Order/Allow/Deny in one file. |
header-action | error | Unknown Header/RequestHeader action — valid: set, append, add, unset, echo, merge. |
errordocument-args | error | ErrorDocument missing its status code or target. |
unclosed-quote | warning | Unclosed quote swallowing the rest of the line. |
options-all | warning | Options All enables everything incl. ExecCGI — list only what you need. |
options-mix | warning | Mixing +/- prefixed Options with bare Options on one line. |
trace-on | warning | TraceEnable On enables the TRACE method (XST risk). |
indexes-exposed | info | Options +Indexes enables directory listing — confirm it is intentional. |
servertokens-full | info | ServerTokens Full advertises the exact version — consider Prod. |
execgi | info | CGI execution enabled — make sure only trusted users can write here. |
dup-rewriteengine | info | Duplicate RewriteEngine On — harmless, one is enough. |
module-note | info | Directive belongs to a module (e.g. mod_rewrite) — verify it is loaded on your server. |
How to check .htaccess syntax online
- Pick the config type (.htaccess, httpd.conf, or VirtualHost snippet).
- Paste your Apache config into the editor (or load a worked example).
- Click Lint config — or keep Live lint on to re-check as you type.
- Review issues grouped by severity; click any issue to jump the cursor to its line.
- Fix errors first, then warnings. Info notes are worth a glance, not necessarily a change.
- Before deploying, still run
apachectl configteston the real server.
Frequently asked questions
Is this Apache linter a replacement for apachectl configtest?
No. This is a heuristic linter, not apachectl configtest. It catches common mistakes — directive typos, invalid RewriteRule flags, unbalanced <IfModule>/<Directory> blocks, directives used in the wrong context (e.g. AllowOverride outside <Directory>), and risky settings — entirely in your browser. But it cannot know which modules are loaded on your server, so module requirements are reported as info notes ("may need mod_rewrite"), not verdicts. Always run apachectl configtest on the server before deploying.
What checks does the Apache .htaccess linter run?
Thirty rules across three severities. Errors: unknown directives (with did-you-mean suggestions), unknown blocks, unclosed/mismatched/stray blocks, directives in the wrong context, invalid RewriteRule and RewriteCond flags, bad Redirect status codes, and unknown Header actions. Warnings: RewriteRule/RewriteCond with no RewriteEngine On, orphan RewriteCond, deprecated Apache 2.2 Order/Allow/Deny syntax, mixing Require with 2.2 syntax, Redirect overlapping a RewriteRule for the same path, Options All, and TraceEnable On. Info: Options +Indexes, ServerTokens Full, ExecCGI, duplicate RewriteEngine On, and per-module requirement notes.
Why was a valid directive flagged as unknown?
The built-in dictionary covers about 120 core, mod_rewrite, and common directives (mod_alias, mod_headers, mod_expires, mod_mime, mod_ssl, mod_proxy, mod_auth*, and more). If your directive comes from a third-party or less common module, the linter cannot know it and flags it — with a closest-match suggestion when it looks like a typo. That flag is a prompt to double-check, not proof of an error.
Can it lint httpd.conf and VirtualHost blocks too, not just .htaccess?
Yes. Use the config-type selector above the editor: ".htaccess" applies per-directory rules (<VirtualHost> and <Directory> are rejected, AllowOverride is rejected), "httpd.conf" applies server-config rules (AllowOverride must sit inside <Directory>), and "VirtualHost snippet" lints as if inside <VirtualHost>. Context-sensitive rules like RewriteBase and ServerName change meaning between modes.
Why do I get "RewriteRule with no RewriteEngine On"?
mod_rewrite silently ignores every RewriteRule, RewriteCond, and RewriteBase until it sees "RewriteEngine On" in the same scope. It is the single most common reason rewrite rules "do nothing". The linter warns on any rewrite directive that appears before the first RewriteEngine On.
Is my Apache config uploaded to a server?
No. The whole linter runs locally in your browser as plain JavaScript — there are zero fetch or XHR calls on this page, which you can verify in the network tab of your browser developer tools. Your configuration never leaves the page, so internal hostnames, paths, and rules stay private.
What is the difference between this and the nginx linter?
Apache and nginx are different servers with different configuration languages — .htaccess/httpd.conf directives versus nginx.conf blocks. This tool only understands Apache syntax; for nginx configuration, use the separate nginx linter linked below.
Free tool by NRTechStudio