.env Validator
Check a .env file for duplicate keys, invalid names and unterminated quotes.
Paste a .env file on the left.
How it works
A `.env` file fails quietly. A loader that hits a malformed line typically either skips it or throws with no line number, and a shadowed key — the same NAME set twice — never surfaces at all, because the last value wins and the earlier one simply never took effect. This checks every line on its own and names the ones a loader would mishandle.
Every line gets a verdict, not just the first bad one
A malformed line does not stop the scan. Real `.env` files are edited by hand over months, and the useful report is "these four lines have a problem," not a single exception pointing at the first one.
What "duplicate key" actually means here
Every real `.env` loader — dotenv, Docker's `--env-file`, Compose — keeps the last occurrence of a repeated key and silently drops the earlier ones. That is not a syntax error, so it produces no error message anywhere else; it is reported here specifically because it is the shadowing bug that is otherwise invisible.
$VAR references are flagged, not resolved
Plain `.env` files do not expand shell-style variable references, so a value of ${DATABASE_URL}
is not an error — it is an honest question about which loader you are targeting, since Compose and `dotenv-expand`
would resolve it and plain `dotenv` would not. Each occurrence is called out so you can check.
Example
PORT=8080 followed later by PORT=3000 reports the first as shadowed — the file's own
later line already overrides it, silently, which is exactly the kind of bug that survives a code review because
nothing about it looks wrong on either line in isolation.
Frequently asked questions
What counts as a duplicate key?
The same NAME assigned twice in one file. Every real .env loader — dotenv, Docker's --env-file, Compose — keeps the last occurrence and drops the earlier ones silently, so the earlier line is reported as shadowed even though nothing about that line is itself malformed.
Why flag a $VAR reference instead of resolving it?
Because whether it resolves depends on the loader, not the file. Plain dotenv leaves ${OTHER_VAR} exactly as written; Docker Compose and dotenv-expand both resolve it. This reports every occurrence so you can check it against whichever loader actually reads this file in production.
It rejected a key with a space or a dash — why?
Because that is not a valid shell environment variable name: letters, digits and underscore only, and it cannot start with a digit. A key that breaks this rule may still parse here, but no shell or process will ever see it set correctly.
Related tools
Env File Converter
Convert between .env, JSON and YAML — the same config in three syntaxes.
LocalEnv Diff
Compare two versions of a config file line by line.
LocalINI ⇄ JSON Converter
Convert INI to JSON and back, with sections becoming nested objects.
LocalTOML to JSON Converter
Parse a TOML document — tables, arrays of tables and all — into JSON.
LocalGitignore Generator & Checker
Generate a .gitignore for common stacks, or check whether a path is actually ignored.
LocalGit URL Parser
Break a git remote URL into protocol, host, owner and repository.
Local