n8n-io/n8n · critical · UnexpectedError

External storage bucket name not configured. Please set `N8N

Error message

External storage bucket name not configured. Please set `N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME`.

What it means

UnexpectedError thrown in the ObjectStoreService constructor when s3Config.bucket.name === ''. The bucket name comes from N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME. Notably this uses UnexpectedError (a code bug class) rather than UserError, which is inconsistent with the Azure equivalent [251]; functionally it still fails fast at DI time when S3 mode is enabled without a bucket.

Source

Thrown at packages/@n8n/blob-storage/src/object-store/object-store.service.ee.ts:48

/** How many per-key delete failures to name in the error before truncating, to keep the message bounded. */
const MAX_REPORTED_DELETE_ERRORS = 5;

@Service()
export class ObjectStoreService {
	private s3Client: S3Client;

	private isReady = false;

	private bucket: string;

	constructor(
		private readonly logger: Logger,
		private readonly s3Config: ObjectStoreConfig,
	) {
		const { bucket } = s3Config;
		if (bucket.name === '') {
			throw new UnexpectedError(
				'External storage bucket name not configured. Please set `N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME`.',
			);
		}

		this.bucket = bucket.name;
		this.s3Client = new S3Client(this.getClientConfig());
	}

	/** This generates the config for the S3Client to make it work in all various auth configurations */
	getClientConfig() {
		const { host, bucket, protocol, credentials, maxAttempts } = this.s3Config;
		const clientConfig: S3ClientConfig = {};
		const endpoint = host ? `${protocol}://${host}` : undefined;
		if (endpoint) {
			clientConfig.endpoint = endpoint;
			clientConfig.forcePathStyle = this.s3Config.forcePathStyle;
		}
		if (bucket.region.length) {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Set N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME to a bucket n8n can read/write.
  2. Verify the variable is present in the running process (printenv).
  3. If S3 is not intended, switch N8N_EXTERNAL_STORAGE_MODE back to filesystem.
  4. Restart n8n after setting the variable.

Example fix

# before
N8N_EXTERNAL_STORAGE_MODE=s3
# bucket name missing

# after
N8N_EXTERNAL_STORAGE_MODE=s3
N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME=n8n-blobs
Defensive patterns

Strategy: validation

Validate before calling

function assertS3Config(env: NodeJS.ProcessEnv) {
  if (env.N8N_EXTERNAL_STORAGE_MODE === 's3' && !env.N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME) {
    throw new Error('N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME must be set when mode=s3');
  }
}

Type guard

const hasS3Bucket = (env: NodeJS.ProcessEnv): boolean =>
  !!env.N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME && env.N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME.length > 0;

Try / catch

try {
  await objectStoreService.init();
} catch (e) {
  if (e instanceof UnexpectedError && /bucket name not configured/.test(e.message)) {
    // halt startup with a clear config-missing message
  }
  throw e;
}

Prevention

When it happens

Trigger: ObjectStoreService is instantiated via DI while N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME is empty AND external storage mode is s3. The constructor check at line 47 throws before any S3 client call.

Common situations: Switching N8N_EXTERNAL_STORAGE_MODE=s3 without setting the bucket env var; a typo in the env var; Helm/Kubernetes values file missing the bucket key; an env loader that strips empty values.

Related errors


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