immich-app/immich · critical · ImmichStartupError
Failed to write "${externalPath} - ${docsMessage}"
Error message
Failed to write "${externalPath} - ${docsMessage}" What it means
Thrown by StorageService.verifyWriteAccess at startup when overwriteFile of the '.immich' marker file fails. This proves the volume is writable, not just creatable; failure aborts startup (ImmichStartupError) with the external path and folder-checks doc link.
Source
Thrown at server/src/services/storage.service.ts:186
this.storageRepository.mkdirSync(folderPath);
await this.storageRepository.createFile(internalPath, Buffer.from(Date.now().toString()));
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'EEXIST') {
this.logger.warn('Found existing mount file, skipping creation');
return;
}
this.logger.error(`Failed to create ${internalPath}: ${error}`);
throw new ImmichStartupError(`Failed to create "${externalPath} - ${docsMessage}"`);
}
}
private async verifyWriteAccess(folder: StorageFolder) {
const { internalPath, externalPath } = this.getMountFilePaths(folder);
try {
await this.storageRepository.overwriteFile(internalPath, Buffer.from(Date.now().toString()));
} catch (error) {
this.logger.error(`Failed to write ${internalPath}: ${error}`);
throw new ImmichStartupError(`Failed to write "${externalPath} - ${docsMessage}"`);
}
}
private getMountFilePaths(folder: StorageFolder) {
const folderPath = StorageCore.getBaseFolder(folder);
const internalPath = join(folderPath, '.immich');
const externalPath = `<UPLOAD_LOCATION>/${folder}/.immich`;
return { folderPath, internalPath, externalPath };
}
}
View on GitHub (pinned to 199723261c)
Solutions
- Confirm the volume is mounted read-write: mount | grep <path>.
- Remove any immutable attribute: chattr -i <UPLOAD_LOCATION>/<folder>/.immich.
- Raise the user's disk quota or move to a volume with space.
- Verify ACLs allow the immich uid to overwrite existing files: getfacl <folder>.
- Re-mount the share writable (CIFS: remove 'ro', NFS: verify exports allow rw).
Example fix
# read-only NFS export mount -o remount,rw /mnt/library
Defensive patterns
Strategy: validation
Validate before calling
import { open, writeFile } from 'node:fs/promises';
async function canOverwrite(p: string) {
try { await writeFile(p, Buffer.from('probe'), { flag: 'r+' }); return true; }
catch { try { await writeFile(p, Buffer.from('probe')); return true; } catch { return false; } }
} Try / catch
try { await storageService.onBootstrap(); }
catch (e) {
if (e instanceof ImmichStartupError && /Failed to write/.test(e.message)) {
// remount share read-write or fix ACLs, then restart
}
} Prevention
- For network mounts, mount with rw and verify with `touch <path>/.immich && rm <path>/.immich`.
- Do not set chattr +i on Immich marker files.
- Keep user quotas above a small floor to survive create+overwrite checks.
When it happens
Trigger: Server boot, folder-integrity phase: storageRepository.overwriteFile(internalPath, Buffer) rejects after createMountFile succeeded, e.g. file became read-only between checks or the FS rejects truncation.
Common situations: NFS/CIFS mount mounted read-only after creation; immutable/chattr +i set on '.immich'; quota exhausted between create and overwrite; container running as a uid that can create but not overwrite due to ACLs.
Related errors
- Failed to read: "${externalPath} (${internalPath}) - ${docsM
- Failed to create "${externalPath} - ${docsMessage}"
- Failed to read helmet file: ${helmetFile}
- Geodata file ${cities500} not found
- Target media location must be an absolute path
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/a686a4f852cd4413.
Report an issue: GitHub.