{"record":{"id":"a686a4f852cd4413","repo":"immich-app/immich","slug":"failed-to-write-externalpath-docsmessage","errorCode":null,"errorMessage":"Failed to write \"${externalPath} - ${docsMessage}\"","messagePattern":"Failed to write \"(.+?) - (.+?)\"","errorType":"exception","errorClass":"ImmichStartupError","httpStatus":null,"severity":"critical","filePath":"server/src/services/storage.service.ts","lineNumber":186,"sourceCode":"      this.storageRepository.mkdirSync(folderPath);\n      await this.storageRepository.createFile(internalPath, Buffer.from(Date.now().toString()));\n    } catch (error) {\n      if ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n        this.logger.warn('Found existing mount file, skipping creation');\n        return;\n      }\n      this.logger.error(`Failed to create ${internalPath}: ${error}`);\n      throw new ImmichStartupError(`Failed to create \"${externalPath} - ${docsMessage}\"`);\n    }\n  }\n\n  private async verifyWriteAccess(folder: StorageFolder) {\n    const { internalPath, externalPath } = this.getMountFilePaths(folder);\n    try {\n      await this.storageRepository.overwriteFile(internalPath, Buffer.from(Date.now().toString()));\n    } catch (error) {\n      this.logger.error(`Failed to write ${internalPath}: ${error}`);\n      throw new ImmichStartupError(`Failed to write \"${externalPath} - ${docsMessage}\"`);\n    }\n  }\n\n  private getMountFilePaths(folder: StorageFolder) {\n    const folderPath = StorageCore.getBaseFolder(folder);\n    const internalPath = join(folderPath, '.immich');\n    const externalPath = `<UPLOAD_LOCATION>/${folder}/.immich`;\n\n    return { folderPath, internalPath, externalPath };\n  }\n}\n","sourceCodeStart":168,"sourceCodeEnd":198,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/storage.service.ts#L168-L198","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# read-only NFS export\nmount -o remount,rw /mnt/library","handlingStrategy":"validation","validationCode":"import { open, writeFile } from 'node:fs/promises';\nasync function canOverwrite(p: string) {\n  try { await writeFile(p, Buffer.from('probe'), { flag: 'r+' }); return true; }\n  catch { try { await writeFile(p, Buffer.from('probe')); return true; } catch { return false; } }\n}","typeGuard":null,"tryCatchPattern":"try { await storageService.onBootstrap(); }\ncatch (e) {\n  if (e instanceof ImmichStartupError && /Failed to write/.test(e.message)) {\n    // remount share read-write or fix ACLs, then restart\n  }\n}","preventionTips":["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."],"tags":["storage","startup","filesystem","permissions","network-mount"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}