n8n-io/n8n · critical · UserError
File not found
Error message
File not found
What it means
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.
Source
Thrown at packages/cli/src/config/index.ts:51
config.getEnv = config.get;
// Load overwrites when not in tests
if (!inE2ETests && !inTest) {
// Overwrite config from files defined in "_FILE" environment variables
Object.entries(process.env).forEach(([envName, fileName]) => {
if (envName.endsWith('_FILE') && fileName) {
const configEnvName = envName.replace(/_FILE$/, '');
// @ts-expect-error convict internal, not typed
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const key = config._env[configEnvName]?.[0] as string;
if (key) {
let value: string;
try {
value = readFileSync(fileName, 'utf8');
} catch (error) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (error.code === 'ENOENT') {
throw new UserError('File not found', { extra: { fileName } });
}
throw error;
}
if (value !== value.trim()) {
console.warn(
`[n8n] Warning: The file specified by ${envName} contains leading or trailing whitespace, which may cause authentication failures.`,
);
}
config.set(key, value);
}
}
});
}
setGlobalState({
defaultTimezone: globalConfig.generic.timezone,
});
View on GitHub (pinned to 5ac6606e81)
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.
Example fix
# before N8N_ENCRYPTION_KEY_FILE=/run/secret/key # typo # after N8N_ENCRYPTION_KEY_FILE=/run/secrets/key
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'fs';
for (const [k, v] of Object.entries(process.env)) {
if (k.endsWith('_FILE') && v && !existsSync(v)) {
throw new Error(`${k} points to missing file: ${v}`);
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unknown agents module: "${moduleName}". ${validTokens ? `Val
- ${claudeConfigPath} not found
- Set N8N_AI_ANTHROPIC_KEY or ANTHROPIC_API_KEY — the judge LL
- Failed to enable MCP access (server reported mcpAccessEnable
- seed.endpoint "${endpoint}" matches no configured LangSmith
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/ad6a40a97d3f24e6.
Report an issue: GitHub.