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

  1. Verify the file exists at the exact path: `ls -l <path-from-env>`.
  2. Fix the mount/volume definition in your deployment so the file is present.
  3. If you no longer want file-based loading, unset the `_FILE` var and use the plain env var instead.
  4. 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

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


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/ad6a40a97d3f24e6. Report an issue: GitHub.