{"record":{"id":"ba580cb759c31c8b","repo":"n8n-io/n8n","slug":"failed-to-read-env-name-file-from-file-file-pat","errorCode":null,"errorMessage":"Failed to read {env_name}_FILE from file {file_path}: {e}","messagePattern":"Failed to read (.+?)_FILE from file (.+?): (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"packages/@n8n/task-runner-python/src/env.py","lineNumber":15,"sourceCode":"import os\nfrom pathlib import Path\n\n\ndef read_env(env_name: str) -> str | None:\n    if env_name in os.environ:\n        return os.environ[env_name]\n\n    file_path_key = f\"{env_name}_FILE\"\n    if file_path_key in os.environ:\n        file_path = os.environ[file_path_key]\n        try:\n            return Path(file_path).read_text(encoding=\"utf-8\").strip()\n        except (OSError, IOError) as e:\n            raise ValueError(\n                f\"Failed to read {env_name}_FILE from file {file_path}: {e}\"\n            )\n\n    return None\n\n\ndef read_str_env(env_name: str, default: str) -> str:\n    value = read_env(env_name)\n    if value is None:\n        return default\n    return value\n\n\ndef read_int_env(env_name: str, default: int) -> int:\n    value = read_env(env_name)\n    if value is None:\n        return default\n    try:","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/task-runner-python/src/env.py#L1-L33","documentation":"Thrown by read_env in the Python task runner when an environment variable's _FILE companion is set but the file it points to cannot be read. The _FILE convention allows secrets to be injected from files (e.g. Docker secrets) rather than plaintext environment variables; read_env tries to read the file when the primary variable is absent, and wraps OSError/IOError in a ValueError with context.","triggerScenarios":"The primary environment variable (e.g. N8N_RUNNERS_GRANT_TOKEN) is unset, but the _FILE variant (e.g. N8N_RUNNERS_GRANT_TOKEN_FILE) is set and points to a path that doesn't exist, is not readable, or has wrong permissions. Path(file_path).read_text() raises OSError or IOError, which is caught and re-raised as ValueError.","commonSituations":"Docker secret or Kubernetes secret mount path is wrong or the secret hasn't been created yet. File permissions don't allow the runner process to read the file. The _FILE path points to a directory instead of a file. Race condition where the runner starts before the secret file is mounted.","solutions":["Verify the file path in the _FILE environment variable exists and is readable by the runner process.","Check file permissions: the runner user must have read access.","Ensure Docker/Kubernetes secrets are mounted before the runner starts (use init containers or proper ordering).","If the file is not needed, unset the _FILE variable and provide the value directly in the primary variable."],"exampleFix":"# before — file doesn't exist\nexport N8N_RUNNERS_GRANT_TOKEN_FILE=/run/secrets/nonexistent\n# after — create the secret or fix the path\ndocker secret create grant_token ./grant_token.txt\nexport N8N_RUNNERS_GRANT_TOKEN_FILE=/run/secrets/grant_token","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\nimport os\n\ndef read_env_file(env_name: str) -> str | None:\n    file_key = f'{env_name}_FILE'\n    if file_key in os.environ:\n        path = Path(os.environ[file_key])\n        if not path.exists():\n            raise FileNotFoundError(f'{file_key} points to non-existent file: {path}')\n        if not os.access(path, os.R_OK):\n            raise PermissionError(f'Cannot read {file_key}: {path}')\n        return path.read_text(encoding='utf-8').strip()\n    return None","typeGuard":null,"tryCatchPattern":"from env import read_env\n\ntry:\n    token = read_env('N8N_RUNNERS_GRANT_TOKEN')\nexcept ValueError as e:\n    print(f'Failed to read secret file: {e}')\n    sys.exit(1)","preventionTips":["Verify _FILE paths exist and are readable before starting the runner.","Use Docker/Kubernetes health checks to verify secret mounts before the container starts.","Ensure file permissions allow the runner process to read secret files.","Prefer the _FILE convention for secrets to avoid leaking them in environment variables."],"tags":["task-runner","python","configuration","secrets","file-io","startup"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}