Artur
Artur
Founder

n8n Environment Variables: The Complete Reference

April 22, 2026

n8n-environment-variablesn8n-configurationself-hosted-n8nn8n-env-vars

N8N_ENCRYPTION_KEY must be set before your first production boot. Without it, stored credentials become undecryptable after restarts - and there's no recovery path. This single variable causes more support tickets than any other n8n configuration issue.

The official docs scatter environment variables across multiple pages (deployment, nodes, endpoints). This reference consolidates everything into one place with production-ready defaults.

How Precedence Works

n8n reads configuration in this order:

  1. Process environment variables (highest priority)
  2. Config files
  3. Built-in defaults (lowest priority)

If you set both VAR and VAR_FILE, the file value wins. Use the _FILE suffix for secrets from mounted volumes or secret managers - keeps plaintext out of your docker-compose.yml (source).

Must-Set Before First Run

These variables cannot be safely changed after your instance has stored data:

VariableWhy It Matters
N8N_ENCRYPTION_KEYEncrypts all stored credentials. Change it later = lost access to every saved credential.
N8N_ENCRYPTION_KEY_FILEAlternative: path to file containing the key. Preferred for container deployments.
DB_TYPESwitching databases after workflows exist requires manual migration.

Set N8N_ENCRYPTION_KEY or N8N_ENCRYPTION_KEY_FILE before first prod boot - official docs and community cheat sheets both emphasize this as the single most critical configuration step (source).

Categorized Reference Table

Database Configuration

VariableDefaultDescription
DB_TYPEsqliteOptions: sqlite, postgresdb, mysqldb, mariadb
DB_POSTGRESDB_HOSTlocalhostPostgreSQL host
DB_POSTGRESDB_PORT5432PostgreSQL port
DB_POSTGRESDB_DATABASEn8nDatabase name
DB_POSTGRESDB_USERrootDatabase user
DB_POSTGRESDB_PASSWORD-Database password
DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZEDtrueSet to false for self-signed certs

Security & Authentication

VariableDefaultDescription
N8N_ENCRYPTION_KEY-Required for production. 32+ character random string.
N8N_BASIC_AUTH_ACTIVEfalseEnable basic auth for UI
N8N_BASIC_AUTH_USER-Basic auth username
N8N_BASIC_AUTH_PASSWORD-Basic auth password
N8N_BLOCK_ENV_ACCESS_IN_NODEfalsePrevents workflows from reading env vars. Set true on shared instances.

Small teams use N8N_BASIC_AUTH_ACTIVE=true with username/password to gate UI access. For shared installs, N8N_BLOCK_ENV_ACCESS_IN_NODE=true prevents workflows from leaking secrets (source).

Webhooks & Endpoints

VariableDefaultDescription
N8N_HOSTlocalhostInternal host n8n listens on
N8N_PORT5678Internal port
N8N_PROTOCOLhttpSet to https when using SSL
WEBHOOK_URL-Public URL for webhooks. Critical behind reverse proxies.
N8N_EDITOR_BASE_URL-Public URL for the editor UI
N8N_PAYLOAD_SIZE_MAX16Max webhook payload in MiB
N8N_FORMDATA_FILE_SIZE_MAX200Max form-data file upload in MiB

Executions & Performance

VariableDefaultDescription
EXECUTIONS_MODEregularOptions: regular, queue (for scaling)
EXECUTIONS_TIMEOUT-1Timeout in seconds. -1 = no timeout.
EXECUTIONS_TIMEOUT_MAX3600Max allowed timeout
EXECUTIONS_DATA_SAVE_ON_ERRORallSave execution data on errors
EXECUTIONS_DATA_SAVE_ON_SUCCESSallSave execution data on success
EXECUTIONS_DATA_PRUNEfalseAuto-delete old executions
EXECUTIONS_DATA_MAX_AGE336Hours to keep executions (if pruning enabled)

SMTP & Email

VariableDefaultDescription
N8N_EMAIL_MODEsmtpEmail sending mode
N8N_SMTP_HOST-SMTP server hostname
N8N_SMTP_PORT465SMTP port
N8N_SMTP_USER-SMTP username
N8N_SMTP_PASS-SMTP password
N8N_SMTP_SSLtrueUse SSL for SMTP
N8N_SMTP_SENDER-From address for emails

Logging & Debugging

VariableDefaultDescription
N8N_LOG_LEVELinfoOptions: error, warn, info, verbose, debug
N8N_LOG_OUTPUTconsoleOptions: console, file
N8N_LOG_FILE_LOCATION-Path for log file (if output=file)

Nodes Configuration

VariableDefaultDescription
NODES_INCLUDE-Comma-separated list of nodes to load (whitelist)
NODES_EXCLUDE-Comma-separated list of nodes to block

Production deployments often exclude high-risk nodes: NODES_EXCLUDE=n8n-nodes-base.executeCommand,n8n-nodes-base.ssh removes shell access entirely (source).

Network & Proxy

VariableDefaultDescription
HTTP_PROXY-Proxy for outbound HTTP requests
HTTPS_PROXY-Proxy for outbound HTTPS requests
NO_PROXY-Comma-separated hosts to bypass proxy
N8N_SSL_KEY-Path to SSL private key
N8N_SSL_CERT-Path to SSL certificate

Behind corporate firewalls, missing proxy vars cause nodes to fail on external API calls silently.

N8N_HOST vs WEBHOOK_URL - The Critical Difference

This trips up most first-time self-hosters:

N8N_HOST and N8N_PORT control what n8n listens on internally. Default: localhost:5678.

WEBHOOK_URL (or N8N_EDITOR_BASE_URL) defines the public external URL that appears in webhook URLs and email links.

When you run n8n behind nginx or Traefik:

  • n8n listens on localhost:5678 internally

  • Your reverse proxy handles SSL termination on https://n8n.yourdomain.com

  • Webhooks need to use the public URL, not localhost

Without WEBHOOK_URL set correctly, your workflow webhook URLs will contain localhost:5678 - which external services obviously cannot reach (source).

Common Misconfigurations

Skipping N8N_PROTOCOL=https: Your instance runs but browsers show security warnings, and some integrations reject non-HTTPS webhook URLs.

Empty NODES_EXCLUDE: Exposes nodes like executeCommand that can run arbitrary shell commands. On shared instances, this is a security hole.

Missing HTTP_PROXY behind corporate networks: Nodes that call external APIs fail silently or timeout. Debug logs show connection refused.

Setting N8N_ENCRYPTION_KEY after first boot: Existing credentials become unreadable. You'll need to re-enter every stored credential manually.

Wrong WEBHOOK_URL with reverse proxy: Webhooks show internal URLs. External services can't reach them. Symptoms: workflows never trigger from external events.

Production .env Template

Copy this as a starting point. Replace placeholder values:

# ===================
# CRITICAL - SET FIRST
# ===================
N8N_ENCRYPTION_KEY=your-32-character-random-string-here

# ===================
# DATABASE
# ===================
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=localhost
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=your-db-password

# ===================
# NETWORK
# ===================
N8N_HOST=0.0.0.0
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.yourdomain.com
N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com

# ===================
# SECURITY
# ===================
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your-strong-password
N8N_BLOCK_ENV_ACCESS_IN_NODE=true
NODES_EXCLUDE=n8n-nodes-base.executeCommand

# ===================
# EXECUTIONS
# ===================
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168
EXECUTIONS_TIMEOUT=300

# ===================
# SMTP (optional)
# ===================
N8N_SMTP_HOST=smtp.yourdomain.com
N8N_SMTP_PORT=587
N8N_SMTP_USER=notifications@yourdomain.com
N8N_SMTP_PASS=smtp-password
N8N_SMTP_SENDER=n8n@yourdomain.com

# ===================
# LOGGING
# ===================
N8N_LOG_LEVEL=info

Generate your encryption key with: openssl rand -hex 32

FAQ

What happens if I change N8N_ENCRYPTION_KEY after storing credentials?

All existing credentials become unreadable. n8n cannot decrypt them with a different key. You'll need to delete and re-create every credential. There's no recovery mechanism.

Do I need WEBHOOK_URL if I'm not using a reverse proxy?

If n8n is directly accessible on its public IP/port, you still want WEBHOOK_URL set to that public address. Otherwise webhook URLs will contain whatever N8N_HOST is set to (often localhost or 0.0.0.0).

Should I use NODES_INCLUDE or NODES_EXCLUDE?

NODES_EXCLUDE is safer for most cases - you block specific risky nodes while keeping access to everything else. NODES_INCLUDE is a whitelist approach useful when you want to lock down to a very specific set of allowed nodes.

How do I use the _FILE suffix for secrets?

Instead of N8N_ENCRYPTION_KEY=mysecret, use N8N_ENCRYPTION_KEY_FILE=/run/secrets/n8n_key and mount a file containing just the secret value. Works with Docker secrets and Kubernetes secrets.

Why aren't my webhooks triggering from external services?

Check WEBHOOK_URL. If it's not set or points to localhost, external services can't reach your n8n instance. The webhook URL in your workflow should match your public domain.


Need help configuring n8n for production? n8n Logic specializes in n8n deployments - from initial setup to complex workflow automation. We handle the infrastructure so you can focus on building.


n8n Environment Variables: The Complete Reference | n8nlogic