vlucas/phpdotenv · error · InvalidFileException
Failed to parse dotenv file. %s
Error message
Failed to parse dotenv file. %s
What it means
Thrown as Dotenv\Exception\InvalidFileException by Parser::parse() (src/Parser/Parser.php:30) when the file content is not valid dotenv syntax. The parser splits content into lines (Lines::process drops comments/blank lines and stitches multiline quoted values), then runs each remaining entry through EntryParser inside a Result chain; the first Result error is rethrown with its concrete reason appended, e.g. 'Failed to parse dotenv file. Encountered an invalid name at [FOO BAR=1].'. This is the library's only syntax-error signal for ->load(), ->safeLoad() and Dotenv::parse().
Source
Thrown at src/Parser/Parser.php:30
final class Parser implements ParserInterface
{
/**
* Parse content into an entry array.
*
* @param string $content
*
* @throws \Dotenv\Exception\InvalidFileException
*
* @return \Dotenv\Parser\Entry[]
*/
public function parse(string $content)
{
return Regex::split("/(\r\n|\n|\r)/", $content)->mapError(static function () {
return 'Could not split into separate lines.';
})->flatMap(static function (array $lines) {
return self::process(Lines::process($lines));
})->mapError(static function (string $error) {
throw new InvalidFileException(\sprintf('Failed to parse dotenv file. %s', $error));
})->success()->get();
}
/**
* Convert the raw entries into proper entries.
*
* @param string[] $entries
*
* @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[], string>
*/
private static function process(array $entries)
{
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[], string> */
return \array_reduce($entries, static function (Result $result, string $raw) {
return $result->flatMap(static function (array $entries) use ($raw) {
return EntryParser::parse($raw)->map(static function (Entry $entry) use ($entries) {
/** @var \Dotenv\Parser\Entry[] */
return \array_merge($entries, [$entry]);View on GitHub (pinned to 416df70283)
Solutions
- Read the text after 'Failed to parse dotenv file.' — it names the exact cause and the offending line (e.g. 'Encountered unexpected whitespace at [FOO=bar baz].').
- Double-quote values containing spaces, '#', '$' or quotes: FOO="bar baz".
- Fix or delete the named line; for multiline values make sure the opening " has a matching closing ".
- Inside double quotes only use escapes \n \r \t \v \f \" \\ \$; for literal text use single quotes (no escapes processed).
- Add a lint step to CI (e.g. dotenv-linter) and validate deployment artifacts with Dotenv::parse() before release.
Example fix
// before (.env) APP_NAME=My App # comment MAIL_DSN="smtp://user\q:pass@host" // after (.env) APP_NAME="My App" # comment MAIL_DSN='smtp://user\q:pass@host'
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight a .env before wiring it into bootstrap (throws the same InvalidFileException on bad syntax):
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidFileException;
try {
Dotenv::parse((string) file_get_contents($dir . '/.env'));
} catch (InvalidFileException $e) {
fwrite(STDERR, $e->getMessage() . \PHP_EOL); // names cause + offending line
exit(1);
} Try / catch
use Dotenv\Exception\InvalidFileException;
use Dotenv\Exception\InvalidPathException;
use Dotenv\Exception\InvalidEncodingException;
try {
Dotenv::createImmutable($dir)->load();
} catch (InvalidFileException $e) {
// syntax error: message contains the exact cause; fail the boot loudly
throw new RuntimeException('Invalid .env syntax: ' . $e->getMessage(), 0, $e);
} catch (InvalidPathException | InvalidEncodingException $e) {
// separate handling for path/encoding problems, see errors 7-10
} Prevention
- Always double-quote values that contain spaces, '#', '$' or quotes.
- Keep a linted .env.example and run a dotenv linter in CI.
- Never hand-edit production .env files from word processors or chat windows.
- Run Dotenv::parse() over the file in a deploy pre-check so bad syntax blocks the release, not the runtime.
When it happens
Trigger: Calling Dotenv::createImmutable($dir)->load() or Dotenv::parse($content) with an entry that EntryParser rejects: a line starting with '=' ('=VALUE' -> 'an unexpected equals'); a name with characters outside [letters digits _ .] after export/quote stripping ('FOO BAR=1', 'FOO-BAR=1' -> 'an invalid name'); an unterminated quoted value ('FOO="bar' or "FOO='bar" -> 'a missing closing quote'); a double-quoted escape outside \\ \" \$ \f \n \r \t \v ('FOO="bar\q"' -> 'an unexpected escape sequence'); unquoted value with embedded whitespace followed by more text ('FOO=bar baz' -> 'unexpected whitespace'); or, rarely, a PCRE failure in the line split ('Could not split into separate lines.').
Common situations: Unquoted values containing spaces or inline '#' comments; secrets with quotes, backslashes or '$'; multiline blocks whose closing quote was deleted; keys with hyphens/spaces copied from docker-compose or shell scripts; hand-edited files pasted from chat/docs that mangled quotes; very large .env files hitting PCRE limits.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Illegal character encoding [%s] specified.
- Conversion from encoding [%s] failed.
- At least one environment file path must be provided.
- Unable to read any of the environment file(s) at [%s].
- Lexer encountered unexpected character [%s].
AI-assisted analysis of vlucas/phpdotenv@416df70283 (2026-08-21).
Data as JSON: /api/errors/8ba0d9046a74a0a2.
Report an issue: GitHub.