Profiles·Public

dotenv

semver>=1.0.0postconditions15functions5last verified2026-06-24coverage score100%

Postconditions: what we check

  • config · missing-env-file
    info
    When.env file does not exist or cannot be read
    ReturnsObject with 'error' property containing the Error instance
    Required handlingCaller MAY check result.error after calling config(). config() does NOT throw on missing .env files — it returns { error }. Most callers intentionally ignore the return value because missing .env is expected in production (env vars set via platform). Only check in development/local.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[1][2]
  • config · parse-error
    info
    When.env file exists but contains a syntax error
    ReturnsObject with 'error' property containing the parse Error instance
    Required handlingCaller MAY check result.error. config() does NOT throw on parse errors — it returns { error }. Unhandled parse errors silently leave process.env in a partially-populated state.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[1][2]
  • config · vault-invalid-dotenv-key
    error
    WhenDOTENV_KEY is set but is malformed (wrong URI format, missing key part, missing environment part, or key is shorter than 64 hex characters)
    ThrowsError with code 'INVALID_DOTENV_KEY'. Messages include: "Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/...", "Missing key part", "Missing environment part", "It must be 64 characters long (or more)".
    Required handlingWhen using .env.vault with DOTENV_KEY, callers MUST wrap config() in a try-catch block. In vault mode config() throws (does not return {error}). A malformed key causes an immediate exception that will crash the process if uncaught.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • config · vault-environment-not-found
    error
    WhenDOTENV_KEY references an environment (e.g. 'production') but the corresponding DOTENV_VAULT_PRODUCTION key is not found in the .env.vault file
    ThrowsError with code 'NOT_FOUND_DOTENV_ENVIRONMENT'. Message: "Cannot locate environment DOTENV_VAULT_<ENVIRONMENT> in your .env.vault file."
    Required handlingWrap config() in try-catch when using vault mode. This error occurs when the vault was built for a different environment than the key references. Common during deployments when DOTENV_KEY from staging is accidentally used in production.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • config · vault-decryption-failed
    error
    WhenDOTENV_KEY is syntactically valid but does not decrypt the vault ciphertext (wrong key for the environment, rotated key no longer matches)
    ThrowsError with code 'DECRYPTION_FAILED'. Message: "Please check your DOTENV_KEY".
    Required handlingWrap config() in try-catch when using vault mode. This is the most common vault error in production — it occurs when the DOTENV_KEY env var is stale or belongs to a different environment's vault. Application starts with no secrets loaded.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • config · vault-missing-data
    error
    WhenThe .env.vault file exists (detected because DOTENV_KEY is set) but its contents cannot be parsed (empty file, corrupted, wrong format)
    ThrowsError with code 'MISSING_DATA'. Message: "Cannot parse <vaultPath> for an unknown reason".
    Required handlingWrap config() in try-catch when using vault mode. A corrupted or empty vault file causes an immediate throw. Secrets are not loaded.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • config · success
    info
    When.env file is found and parsed successfully
    ReturnsObject with 'parsed' key containing the parsed key-value pairs
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • configDotenv · configdotenv-file-not-found
    error
    WhenOne or more paths in options.path do not exist or cannot be read
    ReturnsObject with 'error' property set to the last filesystem error encountered. The 'parsed' key is still present with whatever keys were successfully loaded from other files.
    Required handlingCaller MUST check result.error. When path is an array, configDotenv() continues loading remaining files on error (lastError tracking) but the final result includes the error from the last failed file. Silently missing .env files are a common misconfiguration in containerized deployments.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[3]
  • configDotenv · configdotenv-partial-load-on-multi-path
    warning
    Whenoptions.path is an array of multiple file paths and some exist while others do not
    ReturnsObject with 'parsed' containing keys from successfully loaded files only. 'error' is set to the last error from any failed file even if other files loaded successfully.
    Required handlingWhen using multiple paths, callers relying on all files being present MUST validate result.error AND verify all expected keys exist in result.parsed. The presence of result.error does not mean zero keys were loaded.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[3]
  • parse · parse-silent-skip-on-malformed-lines
    warning
    WhenInput string contains lines that do not match the KEY=VALUE pattern
    ReturnsPlain object containing only the lines that did match. Malformed lines are silently dropped. Return value may be an empty object if no lines match.
    Required handlingCallers MUST NOT rely on parse() throwing to detect malformed input. Silent partial parsing means the returned object may be missing expected keys without any error signal. Callers that need strict validation must implement their own key-presence checks after calling parse().
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[3]
  • parse · success
    info
    Wheninput is a valid .env-format string or Buffer
    ReturnsPlain object with string keys and string values
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • populate · no-override-by-default
    warning
    Whena key already exists on the target object and override is not set to true
    ReturnsExisting value is preserved; parsed value is ignored
    Required handlingCallers that intend to force-update existing values MUST pass { override: true }. Omitting this option causes pre-existing environment variables (e.g., set by the OS or CI) to silently take precedence.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]
  • populate · populate-object-required
    error
    WhenThe parsed argument passed to populate() is not an object (e.g. null, string, number)
    ThrowsError with code 'OBJECT_REQUIRED'. Message: "Please check the processEnv argument being passed to populate".
    Required handlingCallers that build the parsed input dynamically (e.g. from JSON.parse of untrusted input) MUST validate the input is an object before calling populate(). Passing null or a primitive throws synchronously and bypasses any surrounding error handling that only catches async errors.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • decrypt · decrypt-invalid-key-length
    error
    WhenkeyStr is shorter than 64 hex characters (the last 64 chars are sliced for the AES key; a shorter string produces an invalid 32-byte key)
    ThrowsError with code 'INVALID_DOTENV_KEY'. Message: "It must be 64 characters long (or more)".
    Required handlingCallers MUST wrap decrypt() in try-catch. This error indicates the DOTENV_KEY was truncated or corrupted. Attempting decryption with a short key will crash the process.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • decrypt · decrypt-wrong-key
    error
    WhenkeyStr is the correct length but does not decrypt the ciphertext (wrong environment key, key rotation mismatch, or ciphertext tampered with)
    ThrowsError with code 'DECRYPTION_FAILED'. Message: "Please check your DOTENV_KEY". Internally triggered by AES-GCM authentication tag verification failure ("Unsupported state or unable to authenticate data").
    Required handlingWrap decrypt() in try-catch. This is the most actionable error — it means the key and ciphertext do not correspond. Common during key rotation when old ciphertext is paired with a new key. Silent swallowing of this error leaves secrets unloaded.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation
  • [2]
    npmjs.com/package/dotenv
    Dotenv
Source code

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Sources: dotenv

Package: dotenv Version: 16.x (latest) Type: Configuration utility - .env file parsing and environment variable loading Weekly Downloads: 50M+ Last Updated: 2026-02-27


Official Documentation

Primary Documentation

Package Characteristics

dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. It follows the Twelve-Factor App methodology for storing configuration in the environment separate from code.

Core Purpose:

  • Parse .env files into key-value pairs
  • Load environment variables into process.env
  • Support secure configuration management
  • Enable environment-specific settings

API Reference

1. config() Method

Signature:

function config(options?: DotenvConfigOptions): DotenvConfigOutput

interface DotenvConfigOptions {
  path?: string;         // Path to .env file (default: ".env")
  encoding?: string;     // File encoding (default: "utf8")
  debug?: boolean;       // Enable debug output
  override?: boolean;    // Override existing process.env values
  processEnv?: object;   // Target object (default: process.env)
}

interface DotenvConfigOutput {
  parsed?: DotenvParseOutput;  // Parsed key-value pairs
  error?: Error;               // Error if loading failed
}

Purpose: Reads .env file, parses contents, and assigns values to process.env.

Return Value:

  • On success: { parsed: { KEY: 'value', ... } }
  • On failure: { error: Error }

Source: https://github.com/motdotla/dotenv#config

Usage Example:

// Basic usage
require('dotenv').config();

// With options
const result = require('dotenv').config({
  path: '/custom/path/to/.env',
  encoding: 'utf8',
  debug: true,
  override: true
});

// Error handling
if (result.error) {
  throw result.error;
}

Behavioral Claims:

POSTCONDITION 1: File Not Found Errors

  • Claim: If the .env file is not found, config() returns an object with an error property containing the file system error.
  • Severity: ERROR
  • Source: https://github.com/motdotla/dotenv - README "File not found: Check that .env exists in the correct directory"
  • Evidence: Return value structure: { error: Error } when file doesn't exist
  • Common Bug: Developers call config() without checking the error property, causing app to run with missing environment variables

POSTCONDITION 2: Parse Errors

  • Claim: If the .env file contains invalid syntax, config() returns an object with an error property containing the parse error.
  • Severity: ERROR
  • Source: https://github.com/motdotla/dotenv - README "Parse errors: Enable debug: true for console output"
  • Evidence: Parse engine throws errors for invalid syntax
  • Common Bug: Invalid .env syntax silently fails, causing undefined variables

POSTCONDITION 3: Missing Required Variables

  • Claim: config() does not validate that required environment variables are present - developers must check process.env manually.
  • Severity: ERROR
  • Source: Related package dotenv-safe exists specifically to validate required variables
  • Evidence: https://www.npmjs.com/package/dotenv-safe - "MissingEnvVarsError will be thrown if any variables are missing"
  • Common Bug: App uses process.env.API_KEY without checking if it's defined, causing runtime errors or undefined behavior

POSTCONDITION 4: Encoding Errors

  • Claim: If the .env file uses non-UTF-8 encoding and encoding option is not set, parse errors may occur.
  • Severity: WARNING
  • Source: https://github.com/motdotla/dotenv - config options include encoding parameter
  • Evidence: Default encoding is 'utf8', other encodings must be specified
  • Common Bug: Files with special characters fail to parse correctly

2. parse() Method

Signature:

function parse(src: string | Buffer, options?: DotenvParseOptions): DotenvParseOutput

interface DotenvParseOutput {
  [key: string]: string;
}

Purpose: Parses .env format string or Buffer into key-value object. Does NOT modify process.env.

Source: https://github.com/motdotla/dotenv#parse

Usage Example:

const dotenv = require('dotenv');
const buf = Buffer.from('BASIC=basic');
const config = dotenv.parse(buf);
// Returns: { BASIC: 'basic' }

Behavioral Claims:

POSTCONDITION 5: Parse Method Errors

  • Claim: parse() throws errors for invalid syntax (unlike config() which returns errors).
  • Severity: ERROR
  • Source: https://github.com/motdotla/dotenv - parse method throws exceptions
  • Evidence: Function signature does not include error return value
  • Common Bug: Developers call parse() without try-catch, causing unhandled exceptions

3. populate() Method

Signature:

function populate(processEnv: object, parsed: DotenvParseOutput, options?: DotenvPopulateOptions): void

Purpose: Assigns parsed values to target object. Advanced usage for custom implementations.

Source: https://github.com/motdotla/dotenv#populate


Parsing Rules

Syntax Specification

Source: https://github.com/motdotla/dotenv#rules

The dotenv parser follows these rules:

  1. Basic Assignment:

    BASIC=basic
    

    Results in: { BASIC: 'basic' }

  2. Empty Lines:

    • Empty lines are skipped
  3. Comments:

    # This is a comment
    KEY=value  # Inline comment
    
    • Lines beginning with # are comments
    • # marks comment start unless value is quoted
  4. Empty Values:

    EMPTY=
    

    Results in: { EMPTY: '' }

  5. Whitespace Trimming:

    FOO= value
    

    Results in: { FOO: 'value' } (trimmed)

  6. Quoted Values:

    SINGLE='single quoted'
    DOUBLE="double quoted"
    
    • Inner quotes are preserved
    • Whitespace inside quotes is preserved
  7. JSON Values:

    JSON={"foo": "bar"}
    

    Results in: { JSON: '{"foo": "bar"}' }

  8. Multiline Values:

    MULTILINE="new\nline"
    
    • Double-quoted values expand \n to newlines
    • Can use literal line breaks in quoted strings
  9. Backticks:

    BACKTICK=`mixed "quotes"`
    
    • Supported for values with mixed quotes

Multiline Variables

Source: https://github.com/motdotla/dotenv#multiline-values

For multiline content like private keys:

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
Kh9NV...
-----END RSA PRIVATE KEY-----"

Or with escape sequences:

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END RSA PRIVATE KEY-----\n"

Error Handling Patterns

Standard Error Handling

Source: https://github.com/motdotla/dotenv/issues/705 - "dotenv import error handling seems not ideal"

Recommended Pattern:

const result = dotenv.config();
if (result.error) {
  throw result.error;
}
console.log(result.parsed);

Common Mistakes:

  1. No Error Checking:

    // ❌ BAD - Silent failure
    dotenv.config();
    const apiKey = process.env.API_KEY; // undefined if .env missing
    
  2. Missing Variable Validation:

    // ❌ BAD - No validation
    dotenv.config();
    const apiKey = process.env.API_KEY;
    // App crashes later when apiKey is undefined
    
  3. Correct Pattern:

    // ✅ GOOD - Check for errors
    const result = dotenv.config();
    if (result.error) {
      throw new Error(`Failed to load .env: ${result.error.message}`);
    }
    
    // ✅ GOOD - Validate required variables
    const apiKey = process.env.API_KEY;
    if (!apiKey) {
      throw new Error('API_KEY environment variable is required');
    }
    

Environment Variable Injection Vulnerability

Source: https://github.com/google/zx/security/advisories/GHSA-qwp8-x4ff-5h87

Vulnerability: Environment Variable Injection in dotenv.stringify

An attacker with control over environment variable values can inject unintended environment variables into process.env, potentially leading to arbitrary command execution.

Mitigation:

  • Avoid using quotes and backticks in environment variable values
  • Enforce strict validation of environment variables before usage
  • Use dotenvx for encrypted environment files

Security Best Practices

Source: https://github.com/motdotla/dotenv#security-issues

Critical Security Guidelines:

  1. Never Commit .env Files:

    # ✅ Add to .gitignore
    echo ".env" >> .gitignore
    
    • .env files should NEVER be committed to version control
    • Use .env.example as template (without secrets)
  2. Use Encrypted .env Files:

  3. Git Pre-Commit Hooks:

    • Enable hooks to prevent accidental commits of secrets
    • Use tools like git-secrets or similar
  4. Secret Management in Production:

    • Use dedicated secret management tools (AWS Secrets Manager, HashiCorp Vault, etc.)
    • Avoid plaintext .env files in production
  5. Remove Accidentally Committed Secrets:

    • If secrets are committed, remove from git history immediately
    • Rotate all compromised credentials
  6. Report Security Issues:

Common Security Mistakes

Source: Various GitHub issues and security advisories

  1. Credentials in Git:

    # ❌ CRITICAL - Never do this
    git add .env
    git commit -m "Add config"
    git push
    

    Impact: Credentials exposed in git history forever

  2. Logging Parse Errors:

    // ❌ BAD - May leak secrets in logs
    const result = dotenv.config();
    if (result.error) {
      console.error('Failed to load .env:', result.error);
    }
    

    Impact: Sensitive values may appear in error messages

  3. Missing .env in Production:

    // ❌ BAD - App crashes
    dotenv.config(); // File not found in production
    const dbUrl = process.env.DATABASE_URL; // undefined
    db.connect(dbUrl); // Crash
    

    Impact: Application failure, potential exposure


Advanced Usage Patterns

ES6 Module Import

Source: https://github.com/motdotla/dotenv#usage

import 'dotenv/config'

Important: This must be the first import statement due to ES6 module execution order.

Common Mistake: Importing dotenv after other modules that access process.env

Node CLI Preload

node -r dotenv/config script.js

Loads dotenv before application code runs, avoiding the need to require it in code.

Custom Configuration via CLI

node -r dotenv/config script.js \
  dotenv_config_path=/custom/.env \
  dotenv_config_debug=true

Source: https://github.com/motdotla/dotenv/issues/705

Known Issue: When using dotenv.config() directly (not via import), the library doesn't read DOTENV_CONFIG_PATH environment variable, which can cause silent loading failures.


Related Packages

dotenv-safe

Source: https://www.npmjs.com/package/dotenv-safe

Extends dotenv to validate that required environment variables are defined.

Usage:

require('dotenv-safe').config({
  allowEmptyValues: false,
  example: './.env.example'
});

Throws: MissingEnvVarsError if variables in .env.example are missing from .env

Use Case: Enforcing required variables at startup

dotenvx

Source: https://github.com/dotenvx/dotenvx

Successor to dotenv with encryption support. Recommended for secure .env file management.

Features:

  • Encrypt .env files before committing
  • Decrypt at runtime
  • Secure by default

dotenv-parse-variables

Source: https://www.npmjs.com/package/dotenv-parse-variables

Parses environment variables into appropriate types (numbers, booleans, arrays, etc.)


Twelve-Factor App Methodology

Source: https://github.com/motdotla/dotenv#should-i-commit-my-env-file

dotenv implements principles from The Twelve-Factor App:

"Store config in the environment separate from code"

Benefits:

  • Environment-specific settings stay outside codebase
  • Consistency across deployments
  • No config changes in version control
  • Easy environment switching (dev/staging/prod)

Common Error Scenarios

1. File Not Found

Scenario: .env file missing

Error:

{ error: Error: ENOENT: no such file or directory, open '.env' }

Detection:

const result = dotenv.config();
if (result.error && result.error.code === 'ENOENT') {
  console.error('.env file not found');
}

2. Parse Error

Scenario: Invalid syntax in .env file

Example Invalid Syntax:

BROKEN KEY=value  # Space in key name

Error:

{ error: SyntaxError: Unexpected token in .env file }

3. Missing Required Variable

Scenario: App expects variable that isn't defined

dotenv.config();
const apiKey = process.env.API_KEY; // undefined
apiService.connect(apiKey); // TypeError: Cannot read property of undefined

Solution:

const apiKey = process.env.API_KEY;
if (!apiKey) {
  throw new Error('API_KEY environment variable is required');
}

4. Called Too Late

Scenario: dotenv called after variables accessed

// ❌ BAD - dbUrl is undefined
const dbUrl = process.env.DATABASE_URL;
dotenv.config();

Solution:

// ✅ GOOD - config() called first
dotenv.config();
const dbUrl = process.env.DATABASE_URL;

5. Override Not Set

Scenario: Environment variable already exists, .env value ignored

# Shell
export API_URL=https://prod.example.com

# .env file
API_URL=https://dev.example.com
dotenv.config();
console.log(process.env.API_URL); // https://prod.example.com (not overridden)

Solution:

dotenv.config({ override: true });
console.log(process.env.API_URL); // https://dev.example.com (overridden)

Detection Patterns

Pattern 1: Unhandled config() Errors

Bad Pattern:

dotenv.config();
// No error checking

Detection Rule: dotenv.config() call without checking return value's error property

Pattern 2: Missing Variable Validation

Bad Pattern:

dotenv.config();
const apiKey = process.env.API_KEY;
// No validation that apiKey is defined

Detection Rule: process.env access without subsequent undefined check

Pattern 3: parse() Without Try-Catch

Bad Pattern:

const config = dotenv.parse(envString);
// parse() throws on error, no try-catch

Detection Rule: dotenv.parse() call not wrapped in try-catch block


TypeScript Support

Source: https://github.com/motdotla/dotenv - TypeScript definitions included

import * as dotenv from 'dotenv';

const result: dotenv.DotenvConfigOutput = dotenv.config();

if (result.error) {
  throw result.error;
}

const parsed: dotenv.DotenvParseOutput | undefined = result.parsed;

Type Definitions:

  • DotenvConfigOptions
  • DotenvConfigOutput
  • DotenvParseOptions
  • DotenvParseOutput
  • DotenvPopulateOptions

Real-World Impact

Issue #705: Error Handling Concerns

Source: https://github.com/motdotla/dotenv/issues/705

Community feedback indicates the current error handling pattern is "not ideal" because:

  • The error property is not prominently documented in types
  • Easy to miss checking for errors
  • Silent failures are common

Recommendation: Use dotenv-safe for stricter validation

Issue #291: Variables Not Loading

Source: https://github.com/motdotla/dotenv/issues/291

Common issue: "dotenv won't load parsed env variables into process.env"

Causes:

  • File path incorrect
  • Called after variables accessed
  • Override not set when variables already exist
  • File encoding issues

Summary of Nark profiles

High-Priority Postconditions

  1. File not found errors MUST be handled (ERROR severity)
  2. Parse errors MUST be handled (ERROR severity)
  3. Missing required variables MUST be validated (ERROR severity)
  4. parse() calls MUST be wrapped in try-catch (ERROR severity)

Medium-Priority Postconditions

  1. Encoding errors should be handled (WARNING severity)
  2. dotenv.config() should be called before accessing process.env (WARNING severity)
  3. Credentials should never be committed to git (SECURITY severity)

Security Postconditions

  1. .env files MUST be in .gitignore (SECURITY severity)
  2. Environment variable injection vulnerabilities MUST be mitigated (SECURITY severity)
  3. Production deployments should use secret management tools (INFO severity)

References

  1. Official Documentation: https://github.com/motdotla/dotenv
  2. npm Package: https://www.npmjs.com/package/dotenv
  3. Snyk Security: https://snyk.io/advisor/npm-package/dotenv
  4. GitHub Issues: https://github.com/motdotla/dotenv/issues
  5. dotenv-safe: https://www.npmjs.com/package/dotenv-safe
  6. dotenvx (secure successor): https://github.com/dotenvx/dotenvx
  7. Twelve-Factor App: https://12factor.net/config
  8. Environment Variable Injection: https://github.com/google/zx/security/advisories/GHSA-qwp8-x4ff-5h87

Total Lines: 586 Last Updated: 2026-02-27 Confidence: HIGH (official documentation, security advisories, community issues)

Need a different package?
Request a profile