External Task Runner v2.4.8: error when launching runner process

Describe the problem/error/question

I am trying to use external Task Runners with n8n v2.4.8 to import external npm modules (puppeteer-extra). The Task Runner starts but fails to launch the runner process, resulting in a timeout in the n8n UI.

docker logs -f withpostgres-task-runners-1
2026/02/01 18:11:18 INFO Starting launcher’s health check server at port 5680
2026/02/01 18:11:18 INFO [launcher:js] Starting launcher goroutine…
2026/02/01 18:11:18 INFO [launcher:py] Starting launcher goroutine…
2026/02/01 18:11:18 WARN DEPRECATION WARNING: N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT will no longer be automatically passed to runners in a future version. Please add this env var to ‘allowed-env’ or use ‘env-overrides’ in your task runner config to maintain current behavior.
2026/02/01 18:11:18 WARN DEPRECATION WARNING: N8N_RUNNERS_TASK_TIMEOUT will no longer be automatically passed to runners in a future version. Please add this env var to ‘allowed-env’ or use ‘env-overrides’ in your task runner config to maintain current behavior.
2026/02/01 18:11:18 WARN DEPRECATION WARNING: N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT will no longer be automatically passed to runners in a future version. Please add this env var to ‘allowed-env’ or use ‘env-overrides’ in your task runner config to maintain current behavior.
2026/02/01 18:11:18 WARN DEPRECATION WARNING: N8N_RUNNERS_TASK_TIMEOUT will no longer be automatically passed to runners in a future version. Please add this env var to ‘allowed-env’ or use ‘env-overrides’ in your task runner config to maintain current behavior.
2026/02/01 18:11:18 INFO [launcher:py] Waiting for task broker to be ready…
2026/02/01 18:11:18 INFO [launcher:js] Waiting for task broker to be ready…
2026/02/01 18:11:23 INFO [launcher:py] Waiting for launcher’s task offer to be accepted…
2026/02/01 18:11:23 INFO [launcher:js] Waiting for launcher’s task offer to be accepted…
2026/02/01 18:12:17 ERROR [launcher:js] Failed to execute launch command: failed to start runner process: fork/exec node /opt/runners/task-runner-javascript/dist/start.js: no such file or directory

my docker-compose.yml:
n8n:
image: n8nio/n8n:latest
restart: always
environment:

- N8N_RUNNERS_ENABLED=true
- N8N_RUNNERS_MODE=external
- N8N_RUNNERS_ENABLED_TASK_TYPES=javascript,python
- N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
- N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN}
volumes:
- n8n_storage:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
mongodb:
condition: service_healthy
networks:
- n8n-network
expose:
- 5678

task-runners:
build:
context: .
dockerfile: Dockerfile.runners
restart: always
environment:
- N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
- N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN}
- N8N_RUNNERS_ENABLED_TASK_TYPES=javascript,python
- N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT=15
- N8N_RUNNERS_LAUNCHER_HEALTH_CHECK_PORT=5680
depends_on:
- n8n
networks:
- n8n-network

my Dockerfile.runners:
FROM n8nio/runners:latest

USER root

RUN cd /opt/runners/task-runner-javascript
&& pnpm add puppeteer-extra puppeteer-extra-plugin-adblocker @ghostery/adblocker-puppeteer

COPY n8n-task-runners.json /etc/n8n-task-runners.json
RUN chown runner:runner /etc/n8n-task-runners.json && chmod 644 /etc/n8n-task-runners.json

USER runner

my n8n-task-runners.json:
{
“task-runners”: [
{
“runner-type”: “javascript”,
“workdir”: “/home/runner”,
“command”: “/usr/local/bin/node”,
“args”: [
“–disallow-code-generation-from-strings”,
“–disable-proto=delete”,
“/opt/runners/task-runner-javascript/dist/start.js”
],
“health-check-server-port”: “5681”,
“env-overrides”: {
“NODE_FUNCTION_ALLOW_BUILTIN”: “",
“NODE_FUNCTION_ALLOW_EXTERNAL”: “puppeteer-extra,puppeteer-extra-plugin-adblocker,@ghostery/adblocker-puppeteer”
}
},
{
“runner-type”: “python”,
“workdir”: “/home/runner”,
“command”: “/opt/runners/task-runner-python/.venv/bin/python”,
“args”: [
“-m”,
“src.main”
],
“health-check-server-port”: “5682”,
“env-overrides”: {
“PYTHONPATH”: “/opt/runners/task-runner-python”,
“N8N_RUNNERS_STDLIB_ALLOW”: "
”,
“N8N_RUNNERS_EXTERNAL_ALLOW”: “*”
}
}
]
}

What is the error message (if any)?

ERROR [launcher:js] Failed to execute launch command: failed to start runner process: fork/exec node /opt/runners/task-runner-javascript/dist/start.js: no such file or directory
Task request timed out after 60 seconds

Please share your workflow

{
“nodes”: [
{
“parameters”: {
“jsCode”: “const puppeteer = require(‘puppeteer-extra’);\nreturn { status: "Modulo caricato con successo!" };”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
-656,
560
],
“id”: “32030497-225f-4b94-996a-ae6f7985fbfa”,
“name”: “Code in JavaScript”
}
],
“connections”: {},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “51687337d09e3cb8f55257cf8cb69045704945fea4f600d0bf225865548b5f7a”
}
}

Share the output returned by the last node

Task request timed out after 60 seconds

Your Code node task was not matched to a runner within the timeout period. This indicates that the task runner is currently down, or not ready, or at capacity, so it cannot service your task.

If you are repeatedly executing Code nodes with long-running tasks across your instance, please space them apart to give the runner time to catch up. If this does not describe your use case, please open a GitHub issue or reach out to support.

If needed, you can increase the timeout using the N8N_RUNNERS_TASK_REQUEST_TIMEOUT environment variable.

Information on your n8n setup

  • n8n version: 2.4.8
  • Database (default: SQLite): Postgres
  • n8n EXECUTIONS_PROCESS setting (default: own, main): default
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker (Compose)
  • Operating system: Linux (debian)

As per your logs, task runners have been depreciated. Your logs also say you can add “N8N_RUNNERS_TASK_TIMEOUT will no longer be automatically passed to runners in a future version. Please add this env var to ‘allowed-env’ or use ‘env-overrides’ in your task runner config to maintain current behavior.”
If you add that it might fix the error since it says to add that, but in the switch from 1.0 to 2.0, things changed including task runners.

Another thing is ensure this folder exists - ERROR [launcher:js] Failed to execute launch command: failed to start runner process: fork/exec node /opt/runners/task-runner-javascript/dist/start.js: no such file or directory. If it isn’t manually create it and ensure n8n has acsess to it using the Restrict File Acsess env var.

Thanks a lot for your previews response, but it doesn’t work.
I made some edits to files but… ( I wrote \ because the response here I can’t put links so it doesn’t recognize with ), and sorry for my english.

Problem running external task runners (v2.6.3): launcher keeps requesting Python runner even with JavaScript-only config

I’m trying to set up external task runners with n8n 2.6.3 and the n8nio/runners:2.6.3 image, extended to add Puppeteer and related packages for JavaScript Code nodes.

The goal is:

  • n8n 2.6.3 as the main instance (broker)

  • a single external runners container (JavaScript only, no Python)

  • custom n8n-task-runners.json that allowlists Puppeteer packages

However, the runners container keeps crashing with this error:

ERROR Failed to load config: config file at /etc/n8n-task-runners.json does not contain requested runner type: python

Even though my config only defines a JavaScript runner.


Current setup

n8n service (docker-compose)

`n8n:
image: \docker.n8n.io/n8nio/n8n:2.6.3
restart: always
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
- N8N_HOST=${N8N_DOMAIN}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- N8N_SECURE_COOKIE=true
- N8N_BASIC_AUTH_ACTIVE=${N8N_BASIC_AUTH_ACTIVE}
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
- WEBHOOK_URL=\https://${N8N_DOMAIN}/
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${TZ}
- NODE_ENV=production
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}

# Task runners (external mode)
- N8N_RUNNERS_ENABLED=true
- N8N_RUNNERS_MODE=external
- N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
- N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN}

volumes:
- n8n_storage:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
mongodb:
condition: service_healthy
networks:
- n8n-network
expose:
- 5678`

task-runners service (docker-compose)

task-runners: build: context: . dockerfile: Dockerfile.runners container_name: n8n-runners environment: - N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679 - N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN} - N8N_RUNNERS_LAUNCHER_HEALTH_CHECK_PORT=5680 - N8N_RUNNERS_RUNNER_TYPE=javascript volumes: - ./n8n-task-runners.json:/etc/n8n-task-runners.json depends_on: - n8n

So:

  • N8N_RUNNERS_TASK_BROKER_URI uses http:// and points to the n8n service on port 5679, as per the docs for external mode.

  • The same N8N_RUNNERS_AUTH_TOKEN is used in both n8n and task-runners. [Task runners external; Task runner env vars]

Dockerfile for runners

`FROM n8nio/runners:2.6.3

USER root

JS runner: install Puppeteer and related packages

RUN cd /opt/runners/task-runner-javascript &&
pnpm add puppeteer-extra puppeteer puppeteer-core @\ghostery/adblocker-puppeteer

Custom config for runners

COPY n8n-task-runners.json /etc/n8n-task-runners.json

USER runner`

This follows the pattern from the docs for extending n8nio/runners and adding extra dependencies. [Adding extra deps]

n8n-task-runners.json

{ "task-runners": [ { "runner-type": "javascript", "env-overrides": { "NODE_FUNCTION_ALLOW_BUILTIN": "*", "NODE_FUNCTION_ALLOW_EXTERNAL": "puppeteer-extra,puppeteer,puppeteer-core,@ghostery/adblocker-puppeteer", "N8N_RUNNERS_ALLOW_PROTOTYPE_MUTATION": "true" } } ] }

So there is only a JavaScript runner defined, no Python runner at all.


What I already tried

  • Initially I had both JavaScript and Python runners defined in n8n-task-runners.json.
    The launcher then complained about:

runner python: health-check-server-port is required with multiple runners

  • Since I only need JavaScript, I removed the Python block from n8n-task-runners.json, leaving only the JavaScript runner (as shown above).

  • After that, the error changed to:

ERROR Failed to load config: config file at /etc/n8n-task-runners.json does not contain requested runner type: python

  • Based on a community thread, I added N8N_RUNNERS_RUNNER_TYPE=javascript to the task-runners service, to explicitly tell the launcher to use the JavaScript runner type. [Runner type thread]

  • I rebuilt and restarted everything with:

docker compose down docker compose up -d --build

  • Despite this, the n8n-runners container still exits immediately, and docker compose logs -f task-runners always shows:

ERROR Failed to load config: config file at /etc/n8n-task-runners.json does not contain requested runner type: python

  • Because the container exits right away, I can’t easily docker exec into it to inspect environment variables, but the compose file clearly sets N8N_RUNNERS_RUNNER_TYPE=javascript.

What I’m asking for

I would really appreciate help understanding:

  1. Why the launcher in n8nio/runners:2.6.3 is still requesting a python runner type, even though:
  • N8N_RUNNERS_RUNNER_TYPE=javascript is set on the runners container, and

  • n8n-task-runners.json only defines a runner-type: "javascript".

  1. Whether there is:
  • a different or updated way to configure “JavaScript-only” runners in v2.6.3,

  • or any additional environment variables or flags that must be set to avoid the launcher defaulting to python.

  1. If this might be a bug or regression in the task-runner launcher for v2.6.3, and if there is a recommended workaround.

My main goal is simply to have:

  • n8n 2.6.3 in external runners mode,

  • a single runners container with JavaScript only,

  • Puppeteer and related packages available in the Code node via the external runners.

Thank you very much in advance for any guidance or examples you can share.

Hello,

You should have two task runner. one for JS another for Py
in total for containers n8n, JS task runner, Py task runner, DB

then you good to go :slight_smile:
took me while to find out. had this problem for some times