Environment variables blocked in Airtable node on self‑hosted n8n 2.19.5 - expected behavior or misconfiguration?

Hi everyone,
I’m running self‑hosted n8n v2.19.5 on a VPS using Docker Compose. I’m trying to build a production‑ready lead‑gen workflow and ran into something confusing regarding environment variables inside node parameters.

Issue

When I try to reference an environment variable inside the Airtable node (Base → By ID), like this:

Code

{{$env.AIRTABLE_BASE_ID}}

…I get this error directly in the UI:

Code

[ERROR: access to env vars denied]

If I remove the expression brackets and just type plain text, the error disappears.
If I hardcode the Base ID, no error.
If I use $env.AIRTABLE_BASE_ID inside a Function node, it works fine.

So it seems like env vars are available to the runtime, but blocked in UI expressions.

Context

  • Self‑hosted n8n 2.19.5

  • Docker Compose deployment

  • Environment variables defined in docker-compose.yml

  • Airtable Personal Access Token credential works

  • “From List” dropdown throws 403 (expected due to Airtable scopes)

  • The only blocker is env var access inside node parameters

Questions

  1. Is this expected behavior for the free self‑hosted version of n8n 2.x?

  2. Are environment variables intentionally blocked in UI expressions unless using n8n Pro?

  3. What is the recommended workaround for self‑hosted users who want reusable workflows (e.g., storing Base ID in credentials)?

  4. Is there any official documentation explaining this restriction?

Goal

I want to build reusable workflows without hardcoding Base IDs, but I’m trying to understand whether this limitation is by design or if I misconfigured something.

Thanks in advance to anyone who can clarify how env vars are supposed to work in node parameters on self‑hosted 2.x

Information on your n8n setup

  • n8n version: v2.19.5
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker Compose
  • Operating system: Ubuntu

Hi @NE_automation

Yes

No

This

Thanks for the links! I read that doc and through that issue as well. It looks like the change mainly affects env var access inside Code nodes, and can be toggled with N8N_BLOCK_ENV_ACCESS_IN_NODE. In my case, $env works fine in Code nodes - the block isn’t the problem. The issue is that env vars are being denied specifically inside node parameter expressions (e.g., Airtable Base ID), where I get [ERROR: access to env vars denied] even though the variable exists in the container. From what I can tell, this seems to be a separate restriction in the 2.x UI expression system. Just trying to confirm whether this is expected behavior for the free self‑hosted version.

good morning @NE_automation
it’s a security behavior of n8n 2.x
use N8N_BLOCK_ENV_ACCESS_IN_NODE=false and restart your container

Thanks for the suggestion! I already tested N8N_BLOCK_ENV_ACCESS_IN_NODE=false and $env works fine inside Code nodes. The issue I’m running into is different - environment variables are being blocked specifically inside node parameter expressions (like the Airtable “Table” and “Base” fields), where I get access to env vars denied even though the variable exists and Code nodes can read it. I didn’t see anything in the 2.0 breaking‑changes docs about env vars being restricted in UI expressions, so I’m trying to confirm whether this is expected behavior in self‑hosted 2.x.

Thanks everyone for the help! I figured it out - the issue was that I added +bases under Access but forgot to enable schema.bases:read under Scopes. Once I added that scope, everything worked. Appreciate everyone who jumped in.

Mark your answer as a solution so that other members can solve their doubts more easily. Cheers :tada: