n8n 2.41.4 - Database Ping Race and Queue Result Leak


n8n published [email protected] on 30 September 2026. The change with the widest blast radius is the database connection ping. A SELECT 1 whose reply is already queued now counts as success when the event loop was stalled past pingTimeoutMs. The same tag stops queue mode from retaining worker results on processes that did not enqueue the execution, and it stops the public executions API from returning HTTP 500 when stored trace context is incomplete.

The full release notes and downloads are on the GitHub release page. The patch range against the previous tag is [email protected]…[email protected].

DbConnectionMonitor in packages/@n8n/db/src/connection/db-connection-monitor.ts runs SELECT 1 on an interval. raceTimeout pits that query against pingTimeoutMs on the Node event loop.

A stall longer than pingTimeoutMs leaves the reply in the I/O queue. On resume, Node runs due timers before it polls I/O, so the timeout won and the monitor marked a live database down. Requests then get HTTP 503 with body Database is not ready! until a later ping succeeds. On Postgres each false timeout destroys a healthy pool client. After pingMaxFailuresBeforeRecovery consecutive misses the monitor tears the DataSource down and opens a new one. Queries already in flight fail with that rebuild.

Commit fe3c5bc (#39757) awaits setImmediateP from timers/promises when the timer fires, then throws OperationalError with message Database connection timed out. A reply already in the I/O queue wins. A query that never answers still fails, one event loop turn later. pingTimeoutMs is unchanged. An unreachable host still recycles the pool client.

Queue mode leaked memory on every process that did not enqueue the work. af4fa9b (#39725) bounds that map. A worker reports completion with a job-finished progress message, and Bull broadcasts it to every main and every webhook process. ScalingService in packages/cli/src/scaling/scaling.service.ts stored each version 2 payload in jobResults because removeOnComplete: true drops the Redis value before job.finished() can return it. Only the enqueuing process pops the entry.

Support reproduced the growth on 2.38.6 with two mains, one webhook process, and one worker. 5,000 requests through the webhook process added 5,000 entries on both mains. 20,000 requests through the leader added 20,000 entries on the follower and 20,000 on the webhook process. A success keeps about 340 bytes. A failure keeps about 2.8 KB.

The patch writes the payload only when msg.version === 2 and this.activeExecutions.has(msg.executionId) are both true. ActiveExecutions holds the id only on the process that enqueued it, so other processes leave jobResults flat. The caller on the enqueuing process still gets the result. If that set and the enqueue site diverge, the waiter finds nothing. job.finished() can also still hang when the completion event is missed. Old map entries stay until those processes restart.

GET /api/v1/executions/{id} returned HTTP 500 when stored tracingContext failed the public response schema. That schema requires a string traceparent. An empty object failed. A null tracestate failed even when traceparent was set. Webhook rows often stored that null, so status polls failed while the execution row was fine.

Commit 940f65e (#39827) maps the column through toPublicTracingContext in packages/cli/src/public-api/v1/controllers/executions.public.controller.ts before validation. A value that is not a record, a missing traceparent, or an empty traceparent becomes null. A string tracestate is kept. Any other tracestate, including null, is dropped, and the body keeps traceparent alone. Broken rows are fixed on read, for the default GET and for includeData=true. The stored column is not rewritten. Every API process needs this build before those calls return HTTP 200.

Three Cloud editor changes ship in the same tag. #39771 adds an Assistant onboarding thread for new Cloud signups. #39912 shows remaining credits on the Assistant banner for Cloud usage based billing accounts. #39854 points those credit buttons at the top up flow for the same accounts.

That UI runs in the Cloud editor. Self hosted mains, workers, and webhook processes keep the runtime behavior they already had. The runtime changes in this tag are the ping race, the jobResults guard, and the executions read path.