Skip to content
MoveWorkflows

n8n environment variables: config, $env and $vars

Updated 2026-10-21 · 5 min read

"Environment variables" means two different things in n8n. One is instance configuration: the variables you set on a self-hosted n8n container to control ports, URLs, the database and security. The other is values your workflows read, where n8n offers $env, $vars and credentials, each with different rules. This page covers both, including the 2.x default that blocks $env in nodes.

Three places for values a workflow needs

$env.NAME $vars.NAME Credentials
Where you set it Server environment (Docker, systemd) n8n UI, Variables tab n8n UI, Credentials
Available on Self-hosted Cloud Pro, Enterprise; self-hosted Business, Enterprise All
Readable in expressions Only if not blocked Yes No (selected on nodes)
Readable in Code node Only if not blocked Yes No, by design
Encrypted at rest No (it's the process env) No Yes
Good for Instance-level settings (URLs included) IDs, feature flags, short codes API keys, tokens, passwords

Rule of thumb: secrets go in credentials, non-secret config shared across workflows goes in Variables, and $env is for self-hosted setups where Variables aren't on your plan.

$env and N8N_BLOCK_ENV_ACCESS_IN_NODE

$env exposes the n8n instance's environment variables in expressions and the Code node. Whether you can use it is controlled by N8N_BLOCK_ENV_ACCESS_IN_NODE.

The n8n 2.0 breaking changes set its default to true: environment variable access from nodes is blocked. The env var reference table still lists the default as false (security variables), so the docs disagree; on 2.x, expect it to be blocked and set it explicitly.

To allow it:

environment:
  - N8N_BLOCK_ENV_ACCESS_IN_NODE=false
  - API_BASE_URL=https://api.example.com

Then {{ $env.API_BASE_URL }} works in node parameters. Allowing it means anyone who can edit a workflow can read every variable in the n8n process, including database passwords and the encryption key if you pass them as plain env vars. That's why it's blocked by default. If you allow it, keep secrets out of the n8n process env (use _FILE, see below) or don't allow it at all.

Variables ($vars)

Custom Variables are created by instance owners and admins in the Variables tab (docs):

  • Keys up to 50 characters, values up to 1000. The docs limit keys and values to letters, digits and underscores, so values like URLs may be rejected; check in your version.
  • Global (whole instance) or project-scoped (from n8n 1.118.0). A project variable overrides a global one with the same key.
  • All values are strings. $vars.LIMIT is "100", not 100.
  • Read-only in workflows; a missing variable is undefined and doesn't fail the workflow.
// Code node
const region = $vars.REGION;
const limit = Number($vars.PAGE_LIMIT || 100);

Plan availability: n8n Cloud Pro and Enterprise, self-hosted Business and Enterprise. Not on Cloud Starter or the free Community edition.

Configuration variables for self-hosted n8n

The reference lists dozens of groups (overview). These are the ones almost every production instance sets:

Variable Default Why you set it
N8N_HOST localhost Host name n8n runs on
N8N_PORT 5678 HTTP port
N8N_PROTOCOL http https when reached over TLS
N8N_WEBHOOK_URL – Public base URL for webhooks behind a reverse proxy (2.30.0+; WEBHOOK_URL is the deprecated alias)
N8N_EDITOR_BASE_URL – Public editor URL, used in emails and SSO redirects
N8N_PROXY_HOPS 0 Number of reverse proxies; needed for IP allowlists
N8N_ENCRYPTION_KEY Random on first launch Encrypts credentials; set it explicitly
GENERIC_TIMEZONE America/New_York Instance timezone for schedules
DB_TYPE and DB_POSTGRESDB_* SQLite Postgres for production
EXECUTIONS_MODE regular queue for queue mode
EXECUTIONS_TIMEOUT / EXECUTIONS_TIMEOUT_MAX -1 / 3600 Default and maximum workflow timeout in seconds
EXECUTIONS_DATA_PRUNE, EXECUTIONS_DATA_MAX_AGE true, 336 h How long execution history is kept
N8N_PAYLOAD_SIZE_MAX 16 (MiB) Webhook payload limit
N8N_BLOCK_ENV_ACCESS_IN_NODE See above $env access

If webhook URLs in the editor show localhost while n8n sits behind a domain, N8N_WEBHOOK_URL is the variable you're missing.

Code node modules

NODE_FUNCTION_ALLOW_BUILTIN and NODE_FUNCTION_ALLOW_EXTERNAL allow Node.js built-ins and npm packages in the Code node. In 2.x with external task runners, they belong on the runner container, not on the main n8n container. Details: npm packages in n8n.

Keeping secrets out of plain env: _FILE

You can append _FILE to most variables to read their value from a file (basic configuration). With Docker secrets:

services:
  n8n:
    image: n8nio/n8n
    environment:
      - N8N_ENCRYPTION_KEY_FILE=/run/secrets/n8n_key
      - DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/db_password
    secrets: [n8n_key, db_password]
secrets:
  n8n_key:
    file: ./secrets/n8n_key
  db_password:
    file: ./secrets/db_password

The secret values don't appear in docker inspect output; only the file paths do.

External secrets

On Enterprise plans n8n can read secrets from 1Password Connect, AWS Secrets Manager, Azure Key Vault, GCP Secrets Manager, HashiCorp Vault or Infisical, referenced as $secrets in credential fields only. For most teams, credentials plus _FILE for instance config are enough.

Debugging checklist

Symptom Likely cause
$env.X is undefined Access blocked (2.x default) or variable not on this container
$vars not offered Plan doesn't include Variables
Webhook URL shows localhost:5678 N8N_WEBHOOK_URL not set
Credentials fail after redeploy N8N_ENCRYPTION_KEY changed
Schedules off by hours GENERIC_TIMEZONE not set
Variable changed, nothing happened Restart needed; schedule expressions need republishing

From Pipedream environment variables

Pipedream had workspace and project-scoped environment variables, secret by default, read with process.env.NAME in Node.js, os.environ["NAME"] in Python and {{process.env.NAME}} in actions (Pipedream env vars). They aren't included in the workflow export, and secret values can't be viewed in the UI after saving, so get them from the original provider.

Pipedream n8n
Secret env var (API key) Credential
Non-secret env var Variable ($vars) or $env on self-hosted
Project-scoped variable Project-scoped Variable (1.118.0+)
process.env.X in code $vars.X (there's no process in the Code node)

Our converter rewrites process.env.X in wrapped code steps and lists every variable each workflow reads, so you know what to create. The code step checker shows it for a single step; the converter report does it for the whole project. The report and 1 workflow are free. Full export: $3 per workflow, $19 minimum — coming soon. Full secret checklist: Pipedream secrets to n8n.

Not affiliated with Pipedream or n8n.

FAQ

How do I read an environment variable in an n8n workflow?
Use $env.NAME in an expression or Code node on self-hosted n8n. In n8n 2.x access is blocked by default; set N8N_BLOCK_ENV_ACCESS_IN_NODE=false to allow it. On n8n Cloud, use Variables ($vars) instead.
What is the difference between $env and $vars in n8n?
$env reads the server's environment (self-hosted only). $vars reads custom Variables you create in the n8n UI; they're available on Cloud Pro/Enterprise and self-hosted Business/Enterprise.
Should I put API keys in n8n environment variables?
No. Store them as credentials, which are encrypted and can't be read by Code nodes. Use environment variables for instance configuration and Variables for non-secret settings.
Which environment variable sets the webhook URL in n8n?
N8N_WEBHOOK_URL (from n8n 2.30.0) sets the public base URL for webhooks behind a reverse proxy. WEBHOOK_URL is its deprecated alias since 2.35.0.
Can I load n8n environment variables from files?
Yes. Append _FILE to supported variables, for example N8N_ENCRYPTION_KEY_FILE, and point it at a file such as a Docker secret.

Related

Sources