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.LIMITis"100", not100. - Read-only in workflows; a missing variable is
undefinedand 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
- https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables
- https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration
- https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables/security
- https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables/deployment
- https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables/endpoints
- https://docs.n8n.io/build/code-in-n8n/define-custom-variables
- https://docs.n8n.io/changelog/v20-breaking-changes
- https://pipedream.com/docs/workflows/environment-variables