How to Re-Enable Expression Spans in n8n 2.43.8

Introduction

You upgrade a self-hosted n8n instance to 2.43.8, open your tracing backend, and something is missing. Workflow spans are there, node spans are there, but the fine-grained expression.evaluate spans that used to show what individual expressions did are gone. Your collector is healthy, your pipeline is unchanged, and no workflow is failing, so the gap looks like a mystery. It is not a mystery. n8n changed a default in 2.43.8, and one environment variable puts the spans back. This tutorial shows you how to confirm the cause, re-enable the spans, and verify they return, without touching anything else in your observability setup.

Quick answer

Set N8N_EXPRESSION_ENGINE_TRACES_ENABLED=true on every n8n instance, restart n8n, then run a workflow that uses expressions. The expression.evaluate spans return to your OTLP backend, while workflow, node, and agent spans stay exactly as they were.

Evidence

n8n 2.43.8 shipped on October 19, 2026 as a single-fix patch release. Its entire changelog is one line: “core: Turn off expression spans by default (#41310)”. That line is the whole story, and it is confirmed by the pull request itself, which is a backport of PR #41211 to the 2.43 release line. The PR changes the default of N8N_EXPRESSION_ENGINE_TRACES_ENABLED from true to false, and states the remedy in plain language: “Set the variable to true to create them again. Workflow, node and agent spans do not change.”

The reason for the change is stated just as plainly in the same PR: “Expression spans are internal engine telemetry. They must not go to a customer’s OTLP endpoint by default. One customer’s endpoint was flooded with them.” In other words, n8n decided that per-expression spans are debugging detail, not default telemetry, and that shipping them to every operator’s tracing backend by default was doing more harm than good. If you actually use that detail, opting back in is a one-variable change, and the PR’s own test procedure confirms the behavior: with the variable at true, expression spans for slow and failed evaluations appear in the collector again.

This matters because n8n’s native OpenTelemetry support is still new. n8n announced native workflow and node tracing on June 8, 2026, with each workflow execution producing a root span and an optional child span per node, exported over OTLP to backends such as Jaeger, Tempo, Datadog, or Grafana Cloud. Expression spans sit one level deeper than node spans: they record individual expression evaluations inside a node. Losing them does not break tracing, but it does remove the layer that tells you which expression was slow or which one failed, which is precisely the layer you reach for when a workflow misbehaves in production. For the full picture of how n8n tracing fits together, see the official n8n OpenTelemetry announcement, and if you are still planning your upgrade path, our how to update n8n self-hosted guide covers the version checks to run before you touch a production instance.

Prerequisites

  • A self-hosted n8n instance running version 2.43.8 or later. n8n Cloud users cannot set instance environment variables, so this fix does not apply to Cloud.
  • OpenTelemetry already enabled on the instance, with traces flowing to an OTLP backend. At minimum, N8N_OTEL_ENABLED=true and N8N_OTEL_EXPORTER_OTLP_ENDPOINT must already be set and working, because workflow spans arriving normally is how you prove the pipeline itself is fine.
  • Shell or dashboard access to restart n8n. In queue mode, you need access to every worker as well as main, since each process reads its environment at startup.
  • Access to your tracing backend (Jaeger, Tempo, Grafana, or similar) to search for span names.

Step-by-step guide

Step 1: Confirm you are on 2.43.8 or later

Open n8n and go to Settings, then About, and read the version number. From the command line, n8n --version prints the same number, and in Docker the image tag tells you directly:

docker ps --format '{{.Image}} {{.Names}}'

If the version is below 2.43.8, expression spans were still on by default, so missing spans point to a different problem, most likely OpenTelemetry not being enabled at all. If the version is 2.43.8 or later, continue: the changed default is the prime suspect.

Step 2: Confirm OpenTelemetry itself still works

Check that workflow and node spans are still arriving in your backend. Run any workflow, then search your backend for its recent traces. If workflow spans appear but expression.evaluate spans do not, your pipeline is healthy and only the expression layer is off. That split, workflow spans present and expression spans absent, is the fingerprint of the 2.43.8 default change, and it rules out collector outages, wrong endpoints, and broken exporters in one check.

You can also confirm the current setting inside a running container:

docker exec <container-name> printenv | grep N8N_EXPRESSION_ENGINE_TRACES_ENABLED

No output means the variable is unset, which on 2.43.8 or later means the new default of false applies. That is the expected state after the upgrade, not a misconfiguration.

Step 3: Search your backend for expression.evaluate spans

Before changing anything, establish the baseline. In Jaeger, select your n8n service and search for the operation expression.evaluate over the last day. In Tempo or Grafana, the equivalent is a TraceQL query such as:

{ span.name = "expression.evaluate" }

You should find spans from before the 2.43.8 upgrade and none after it. That before-and-after boundary, aligned with your upgrade date, confirms the diagnosis and gives you a clean comparison point for the verification step later.

Step 4: Set N8N_EXPRESSION_ENGINE_TRACES_ENABLED=true

Add the variable wherever your n8n environment is defined. The exact spot depends on how you run n8n, but the variable name and value are identical in every case.

For Docker Compose, add one line to the environment block:

services:
  n8n:
    image: n8nio/n8n:2.43.8
    environment:
      - N8N_OTEL_ENABLED=true
      - N8N_OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
      - N8N_EXPRESSION_ENGINE_TRACES_ENABLED=true

For a plain docker run setup, add -e N8N_EXPRESSION_ENGINE_TRACES_ENABLED=true to the command. For an npm or systemd install, add export N8N_EXPRESSION_ENGINE_TRACES_ENABLED=true to the environment file or unit that starts n8n, alongside the existing N8N_OTEL_ENABLED line. In Kubernetes, add it to the container env list in the deployment manifest. Keep your existing OpenTelemetry variables untouched: this change adds one variable, it does not replace your tracing configuration.

Step 5: Restart every n8n process

Environment variables are read at startup, so a restart is mandatory, and in queue mode it must cover every process, not just main. Restarting only main while workers still run the old environment leaves expression spans missing on every execution that lands on a worker, which looks exactly like an intermittent failure.

docker compose up -d

For npm or systemd installs, restart the service with systemctl restart n8n or your equivalent, and repeat on each worker host. After the restart, re-run the printenv check from Step 2 and confirm the variable now prints true.

Step 6: Verify the spans return

Run a workflow that uses expressions, then search your backend for expression.evaluate again. One important nuance from the upstream test procedure: n8n emits expression spans for slow and failed evaluations, not for every expression. A fast workflow where every expression succeeds may legitimately produce no expression spans, and that is not a sign the fix failed. To force a visible span, include an expression that fails, for example a reference to a field that does not exist, or one that is slow enough to cross the slow-evaluation threshold, then check the backend again. When the span appears with the workflow’s trace ID as its parent, the fix is confirmed end to end.

Step 7: Decide whether to keep the spans on

Treat re-enabling as a debugging window, not a permanent setting, unless you have a concrete reason to keep it. The upstream change exists because one operator’s endpoint was flooded, and expression-heavy workflows generate a large number of these spans. A practical pattern is to enable the variable while you chase a specific expression problem, then set it back to false and restart once the problem is resolved. If you need the spans long term, filter or sample them at your collector instead of storing every one, so your backend does not inherit the flood problem that motivated the default change in the first place. The broader n8n complete guide puts this kind of tuning in context alongside the rest of a production self-hosted setup, and our install n8n on Ubuntu VPS tutorial covers the Docker Compose layout used in Step 4 if you are setting up a fresh instance.

Troubleshooting

Spans are still missing after the restart

First, re-check that the variable is actually present in the running process with the printenv command from Step 2. A Compose file edited but not re-applied, or a systemd unit edited without a daemon reload, leaves the old environment in place. Second, in queue mode, verify every worker, not just main: an un-restarted worker silently serves executions without the variable. Third, confirm OpenTelemetry itself is on. If N8N_OTEL_ENABLED is not true, no spans of any kind are exported, and the expression variable has nothing to restore.

The tracing backend is flooded again

That is the exact problem the 2.43.8 default change was fixing. Expression spans are verbose by design, and a workflow with many expressions across many executions multiplies them fast. Narrow the blast radius: enable the variable only on a staging instance while debugging, sample or drop expression.evaluate spans at the collector for production, or turn the variable back to false once the investigation is done. Do not raise collector retention to absorb the flood, since that just moves the cost downstream.

A failing expression produces no span

Check two things. First, confirm the workflow actually ran after the restart, not before it, since spans only reflect the environment of the process that executed them. Second, confirm the failure is an expression evaluation failure, not a node configuration error or a downstream API error: those produce node error spans and execution logs, but not expression.evaluate spans. The execution view in n8n itself remains the fastest place to read the error message, with the span supplying the timing and trace context around it.

The variable seems to have no effect on an older version

On versions before 2.43.8 the default was already true, so setting it explicitly changes nothing. If spans are missing on an older version, the cause is elsewhere: OpenTelemetry disabled, a wrong OTLP endpoint, or a collector that is not receiving data. Upgrade to 2.43.8 or later first if you want the current tracing behavior, and use our how to update n8n self-hosted guide to do it safely.

FAQ

The FAQ entries are in the front matter above, and the key points are worth restating here. Upgrading to 2.43.8 costs you only the expression layer of tracing, never workflow or node spans. Re-enabling costs one variable and a restart, and it touches no metrics. The two most common surprises after re-enabling are the slow-and-failed-only emission rule, which makes healthy workflows look span-free, and queue mode workers that were never restarted. Both are easy to check once you know to look for them.

Conclusion

n8n 2.43.8 turned expression spans off by default because they are internal engine telemetry that was flooding at least one operator’s endpoint, and the project made the opt-in explicit rather than silent. If you relied on expression.evaluate spans, setting N8N_EXPRESSION_ENGINE_TRACES_ENABLED=true and restarting every n8n process restores them, with workflow, node, and agent spans untouched. Keep the spans on while they earn their keep, and switch them off again when the debugging is done. Next, if your tracing setup is still new, read our OpenTelemetry tracing tutorial for Claude Managed Agents for a contrasting example of how another platform structures its spans, and keep the n8n complete guide bookmarked for the rest of your production checklist.

Frequently asked questions

Do I lose workflow or node traces when I upgrade to n8n 2.43.8?

No. The 2.43.8 change stops only expression.evaluate spans. Workflow spans, node spans, and agent spans are unaffected, so your existing traces keep their overall shape and only the expression-level detail disappears.

Does re-enabling expression spans change expression metrics?

No. The metrics toggle is a separate variable, N8N_EXPRESSION_ENGINE_OBSERVABILITY_ENABLED, and it stays true. Flipping the traces variable back on restores spans only, with no change to the metrics n8n already emits.

Why do I still see no expression spans after setting the variable to true?

Two common reasons. First, n8n emits expression spans only for slow and failed evaluations, so a fast, successful workflow may legitimately produce none; test with a deliberately failing or slow expression. Second, every n8n process reads the variable at startup, so in queue mode you must restart the workers as well as main.

Can n8n Cloud users re-enable expression spans?

No. The fix is an environment variable on the n8n process, and Cloud users cannot set instance environment variables. This tutorial applies to self-hosted n8n only, whether you run it with Docker, npm, or Kubernetes.

Should I leave expression spans on permanently?

Only while you are actively debugging expressions. The spans are verbose internal engine telemetry, and a flooded customer endpoint is exactly why n8n changed the default. Turn them on for a debugging window, then set the variable back to false.

Does this change affect how my workflows execute?

No. Expression spans are pure telemetry. They record what the expression engine did, but they do not change evaluation results, execution order, or workflow output in any way.

TP
ToolPilot Team

We install, break, and fix automation tools so you don't have to. Every tutorial on ToolPilot is tested hands-on before publishing.

Keep reading