Skip to content
ZeroServer.tools

Nginx Config Validator

Check an nginx configuration the way nginx -t reads it: syntax, unknown directives, contexts, arguments and duplicates.

Drop a .conf file or click to browse

Nginx Config Validator

This validator reads a configuration the way nginx -t does, without a server. Line breaks are ordinary spaces, so a log_format or server_name list may run over several lines, and a # starts a comment only at the start of a word, so a URL fragment is safe. Every directive is checked against nginx's own command tables: unknown names, with a suggestion for typos such as server_names; directives in the wrong block, such as listen inside http; the wrong number of arguments; on/off values; settings nginx refuses twice in one block, such as root; and nested or duplicate locations nginx rejects. A missing semicolon is reported where it is missing, including the case nginx accepts silently, where the next line becomes extra arguments. Run nginx -t on the server as the final check, since included files and installed modules are only visible there. All processing happens in your browser; no configuration data is uploaded.

Built and maintained by Meet Shah · Last updated

What this tool is used for

  • Catching an unbalanced brace before a restart, which would leave the site down.
  • Checking a config generated by a template for a directive in the wrong context.
  • Reviewing a change from a colleague when you have no server to test against.
  • Spotting a missing semicolon in a long file, including one nginx would accept silently.
  • Sanity-checking a snippet from a blog post before pasting it into production.

How it works in practice

A worked example

A sysadmin turns on directory listings for a downloads folder, edits the location block over SSH, and pastes the server block here before reloading the live server.

Input
server {
    listen 80;
    server_name files.example.com;
    root /srv/files;

    location /downloads/ {
        index index.html
        autoindex on;
    }
}
Output
1 warning
Line 7  No ";" at the end of line 7, so nginx reads "autoindex on" on line 8 as more arguments of "index". nginx -t passes, but "autoindex" is never applied.  warning

nginx treats a line break as ordinary space and reads each directive up to its semicolon, so lines 7 and 8 form one statement: index with three arguments. The index directive takes any number of file names, so nginx has no reason to object. The validator looks for the signature of a lost semicolon instead, a later line of the same statement that begins with a known directive followed by its own argument, and reports it on the line where the semicolon belongs. It says warning rather than error because nginx -t really does pass.

The edge case that catches people

That pass is the trap. nginx treats autoindex and on as two more index file names, so it looks for files with those names in the folder and never turns listings on. With no index.html there either, a request for /downloads/ gets 403 Forbidden, and the error log says that directory index of the folder is forbidden. Had the swallowed line been a directive that breaks the first one's rules, such as a second argument to root, nginx -t would have failed, and the validator reports those cases as errors.

When not to use this tool

Skip it for configs assembled from many included files, since it sees only what you paste, and for third-party modules beyond nginx's own tables, which it can only flag as unknown. For automated review of a whole tree, the nginx team's crossplane parses a configuration into JSON, and gixy flags risky patterns, such as alias path traversal, that are perfectly valid syntax. On the server, nginx -T prints every file nginx actually loaded, includes and all.

Frequently Asked Questions

What does it check?
Syntax as nginx reads it, then each directive against nginx's command tables: unknown names, with a suggestion for typos; the blocks it may sit in; argument counts and on/off values; repeats nginx refuses; and nested or duplicate locations. A # starts a comment only at the start of a word, so a URL fragment is safe.
Does it replace nginx -t?
No. nginx -t loads the real config with your installed modules, resolves include globs and opens the certificate and other files it names. This reads only what you paste, against open-source nginx and NGINX Plus directives, so use it before you deploy and nginx -t before you reload.
Why does nginx complain a directive is not allowed here?
Because each directive is legal only in certain blocks. root works in http, server, location and an if inside a location; listen only in server; worker_processes only at the top level. For a misplaced directive, this page names the blocks nginx accepts it in.
What is the most dangerous config mistake?
The ones nginx accepts. A missing semicolon usually stops nginx loading, but before a line that a list directive such as index can absorb, nginx reads the next directive as more file names and starts without it. A location prefix that matches more paths than intended also passes every check, nginx -t included.
How do I apply a change safely?
Run nginx -t, then nginx -s reload: the master starts new workers with the new config and lets the old ones finish their connections, and if the new config fails to load it keeps the old one running. A full restart stops nginx first, so a broken config leaves the site down.

Common errors and gotchas

  • Treating a syntax pass as a working config. Valid syntax can still route to the wrong place.
  • Putting a directive where it is legal but not meant, such as add_header in http, which any location with its own add_header then silently drops.
  • Forgetting a semicolon, which makes the error appear on a later line than the mistake.
  • Assuming an included file is checked. Includes are resolved by the server, not by a text-level check.
  • Relying on this instead of the server's own test command, which is the only authority on its own config.

Related Formatters & Validators tools

Private & free — this tool runs entirely in your browser.

IndieKit — Ship your Next.js startup in days.affiliate