{"record":{"id":"d8e583878afba27e","repo":"n8n-io/n8n","slug":"environment-variable-n8n-runners-grant-token-is-re","errorCode":null,"errorMessage":"Environment variable N8N_RUNNERS_GRANT_TOKEN is required","messagePattern":"Environment variable N8N_RUNNERS_GRANT_TOKEN is required","errorType":"validation","errorClass":"ConfigurationError","httpStatus":null,"severity":"critical","filePath":"packages/@n8n/task-runner-python/src/config/task_runner_config.py","lineNumber":76,"sourceCode":"    max_payload_size: int\n    task_timeout: int\n    auto_shutdown_timeout: int\n    graceful_shutdown_timeout: int\n    stdlib_allow: set[str]\n    external_allow: set[str]\n    builtins_deny: set[str]\n    env_deny: bool\n    allow_transitive_imports: bool\n\n    @property\n    def is_auto_shutdown_enabled(self) -> bool:\n        return self.auto_shutdown_timeout > 0\n\n    @classmethod\n    def from_env(cls):\n        grant_token = read_str_env(ENV_GRANT_TOKEN, \"\")\n        if not grant_token:\n            raise ConfigurationError(\n                \"Environment variable N8N_RUNNERS_GRANT_TOKEN is required\"\n            )\n\n        task_timeout = read_int_env(ENV_TASK_TIMEOUT, DEFAULT_TASK_TIMEOUT)\n        if task_timeout <= 0:\n            raise ConfigurationError(\n                f\"Task timeout must be positive, got {task_timeout}\"\n            )\n\n        auto_shutdown_timeout = read_int_env(\n            ENV_AUTO_SHUTDOWN_TIMEOUT, DEFAULT_AUTO_SHUTDOWN_TIMEOUT\n        )\n        if auto_shutdown_timeout < 0:\n            raise ConfigurationError(\n                f\"Auto shutdown timeout must be non-negative, got {auto_shutdown_timeout}\"\n            )\n\n        graceful_shutdown_timeout = read_int_env(","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/task-runner-python/src/config/task_runner_config.py#L58-L94","documentation":"Thrown by TaskRunnerConfig.from_env when the N8N_RUNNERS_GRANT_TOKEN environment variable is empty or unset. The grant token is the shared secret the Python runner uses to authenticate with the n8n task broker; without it the runner cannot register or receive tasks, so this is a hard startup requirement.","triggerScenarios":"The Python task runner starts and read_str_env(ENV_GRANT_TOKEN, '') returns an empty string because the environment variable N8N_RUNNERS_GRANT_TOKEN is not set or is set to an empty value. The check `if not grant_token` fires immediately in from_env.","commonSituations":"Starting the Python runner without configuring the grant token. The token was set on the n8n main process but not propagated to the runner's environment. Docker/Kubernetes deployment missing the environment variable. Using the runner in external mode where the token must be explicitly provided.","solutions":["Set N8N_RUNNERS_GRANT_TOKEN to the same grant token configured on the n8n main process.","If running in Docker, add the environment variable to the runner container's env section.","If the token is generated dynamically by n8n, ensure the runner is started by n8n (not manually) so the token is passed.","Use the _FILE suffix variant (N8N_RUNNERS_GRANT_TOKEN_FILE) to read the token from a file if injecting via secrets."],"exampleFix":"# before — missing or empty\n# (N8N_RUNNERS_GRANT_TOKEN not set)\n# after\nexport N8N_RUNNERS_GRANT_TOKEN='your-grant-token-here'","handlingStrategy":"validation","validationCode":"import os\n\ngrant_token = os.environ.get('N8N_RUNNERS_GRANT_TOKEN', '')\nif not grant_token:\n    # Also check _FILE variant\n    token_file = os.environ.get('N8N_RUNNERS_GRANT_TOKEN_FILE')\n    if token_file:\n        grant_token = open(token_file).read().strip()\n    if not grant_token:\n        raise RuntimeError('N8N_RUNNERS_GRANT_TOKEN is required')","typeGuard":null,"tryCatchPattern":"from config.task_runner_config import ConfigurationError\n\ntry:\n    config = TaskRunnerConfig.from_env()\nexcept ConfigurationError as e:\n    if 'GRANT_TOKEN' in str(e):\n        print('Set N8N_RUNNERS_GRANT_TOKEN to the token from n8n')\n    sys.exit(1)","preventionTips":["Always set the grant token when deploying the Python runner.","Use the _FILE variant for secrets in Docker/Kubernetes.","Ensure the token matches between n8n main process and the runner."],"tags":["task-runner","python","configuration","authentication","startup"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}