{"record":{"id":"ad6a40a97d3f24e6","repo":"n8n-io/n8n","slug":"file-not-found","errorCode":null,"errorMessage":"File not found","messagePattern":"File not found","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"critical","filePath":"packages/cli/src/config/index.ts","lineNumber":51,"sourceCode":"config.getEnv = config.get;\n\n// Load overwrites when not in tests\nif (!inE2ETests && !inTest) {\n\t// Overwrite config from files defined in \"_FILE\" environment variables\n\tObject.entries(process.env).forEach(([envName, fileName]) => {\n\t\tif (envName.endsWith('_FILE') && fileName) {\n\t\t\tconst configEnvName = envName.replace(/_FILE$/, '');\n\t\t\t// @ts-expect-error convict internal, not typed\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\tconst key = config._env[configEnvName]?.[0] as string;\n\t\t\tif (key) {\n\t\t\t\tlet value: string;\n\t\t\t\ttry {\n\t\t\t\t\tvalue = readFileSync(fileName, 'utf8');\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\tif (error.code === 'ENOENT') {\n\t\t\t\t\t\tthrow new UserError('File not found', { extra: { fileName } });\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (value !== value.trim()) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[n8n] Warning: The file specified by ${envName} contains leading or trailing whitespace, which may cause authentication failures.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconfig.set(key, value);\n\t\t\t}\n\t\t}\n\t});\n}\n\nsetGlobalState({\n\tdefaultTimezone: globalConfig.generic.timezone,\n});\n","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/config/index.ts#L33-L69","documentation":"Thrown at config-load time when an environment variable ending in `_FILE` points at a path that does not exist (`readFileSync` throws `ENOENT`). n8n supports `_FILE` variants of secret-bearing env vars (e.g. `N8N_ENCRYPTION_KEY_FILE`, `DB_PASSWORD_FILE`) so secrets can be loaded from a mounted file rather than the process environment. The thrown UserError includes `{ extra: { fileName } }` for diagnostics.","triggerScenarios":"Setting `N8N_ENCRYPTION_KEY_FILE=/run/secrets/key` when that file is absent; Kubernetes secret mount misconfigured; Docker volume not attached; typo in the path.","commonSituations":"Container orchestration where the secret mount name differs from the env var path; rotating secrets and forgetting to redeploy the mount; running locally with a stale `.env` that references a file that was deleted.","solutions":["Verify the file exists at the exact path: `ls -l <path-from-env>`.","Fix the mount/volume definition in your deployment so the file is present.","If you no longer want file-based loading, unset the `_FILE` var and use the plain env var instead.","Ensure the n8n process has read permission on the file."],"exampleFix":"# before\nN8N_ENCRYPTION_KEY_FILE=/run/secret/key   # typo\n# after\nN8N_ENCRYPTION_KEY_FILE=/run/secrets/key","handlingStrategy":"validation","validationCode":"import { existsSync } from 'fs';\nfor (const [k, v] of Object.entries(process.env)) {\n  if (k.endsWith('_FILE') && v && !existsSync(v)) {\n    throw new Error(`${k} points to missing file: ${v}`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add a container startup probe that asserts every `*_FILE` path exists and is readable.","Prefer orchestrator-managed secrets (Kubernetes Secret, Docker Compose secrets) over hand-mounted files."],"tags":["config","secrets","env","filesystem","user-error"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}