immich-app/immich · critical · ImmichStartupError
Failed to read: "${externalPath} (${internalPath}) - ${docsM
Error message
Failed to read: "${externalPath} (${internalPath}) - ${docsMessage}" What it means
Thrown by Immich's StorageService.verifyReadAccess at startup when it cannot read the '.immich' mount-marker file inside a configured storage folder. The check exists so the server fails fast (ImmichStartupError) rather than silently corrupting assets on a mis-mounted volume. The message includes the external upload path, the internal resolved path, and a link to docs.immich.app/administration/system-integrity#folder-checks.
Source
Thrown at server/src/services/storage.service.ts:161
}
try {
await this.storageRepository.unlink(file);
} catch (error: any) {
this.logger.warn('Unable to remove file from disk', error);
}
}
return JobStatus.Success;
}
private async verifyReadAccess(folder: StorageFolder) {
const { internalPath, externalPath } = this.getMountFilePaths(folder);
try {
await this.storageRepository.readFile(internalPath);
} catch (error) {
this.logger.error(`Failed to read (${internalPath}): ${error}`);
throw new ImmichStartupError(`Failed to read: "${externalPath} (${internalPath}) - ${docsMessage}"`);
}
}
private async createMountFile(folder: StorageFolder) {
const { folderPath, internalPath, externalPath } = this.getMountFilePaths(folder);
try {
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}"`);
}
}
View on GitHub (pinned to 199723261c)
Solutions
- Verify the host directory for the failing folder exists and is mounted into the container at the path shown in externalPath.
- Ensure the immich server process uid owns or can read the '.immich' file: chown -R <immich-uid>:<immich-gid> <UPLOAD_LOCATION>.
- Check the docker-compose volume mapping for the named folder matches StorageCore.getBaseFolder defaults.
- If using an external library, confirm the library path is accessible inside the container (docker exec ... ls).
- Temporarily remove IMMICH_LOG_LEVEL noise and inspect the preceding log line 'Failed to read (<internalPath>): <error>' for the OS errno.
Example fix
# before: read-only bind volumes: - /mnt/photos:/usr/src/app/upload:ro # after: read-write, correct uid volumes: - /mnt/photos:/usr/src/app/upload
Defensive patterns
Strategy: validation
Validate before calling
import { access, constants } from 'node:fs/promises';
import { join } from 'node:path';
async function canReadImmichMarker(uploadRoot: string, folder: string) {
const p = join(uploadRoot, folder, '.immich');
try { await access(p, constants.R_OK); return true; }
catch { return false; }
}
// run for every StorageFolder before starting the server Try / catch
try {
await storageService.onBootstrap(); // triggers verifyReadAccess
} catch (e) {
if (e instanceof ImmichStartupError && e.message.startsWith('Failed to read')) {
// surface a runbook to the operator, do not retry blindly
}
throw e;
} Prevention
- Run a pre-flight container that execs `ls -la <UPLOAD_LOCATION>/*/.immich` before starting the server.
- Pin the immich uid/gid in your compose file and chown host paths to match.
- Mount library/upload volumes read-write and verify with `mount` before deploy.
- Add a healthcheck that fails on ImmichStartupError so orchestrators do not mark the pod ready.
When it happens
Trigger: Server boot, during the per-folder access verification loop, when storageRepository.readFile(internalPath) rejects for any of the StorageFolder entries (library, upload, encoded, etc.). The thrown error stops startup.
Common situations: UPLOAD_LOCATION/bind-mount is read-only or owned by root; the folder was deleted after the container started; an external library path is not mounted into the container; NFS/CIFS mount dropped; permissions do not allow the immich process uid to read.
Related errors
- Failed to create "${externalPath} - ${docsMessage}"
- Failed to write "${externalPath} - ${docsMessage}"
- Invalid import path: ${path.message}
- Failed to read helmet file: ${helmetFile}
- Geodata file ${cities500} not found
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/709b90fb818390d5.
Report an issue: GitHub.