immich-app/immich · critical · Error
Detected an inconsistent media location. For more…
Error message
Detected an inconsistent media location. For more information, see https://docs.immich.app/errors#inconsistent-media-location
What it means
On startup (onBootstrap), Immich compares the stored previous media location with the current one; if they differ and the new external path is not a subpath of the previous one, it throws rather than attempting a migration, because an automatic path migration would be unsafe.
Solutions
- Restore the original mount path so data sits where Immich expects it, or make the new location a subdirectory of the old path so a migration is possible.
- If the move is intentional and paths aren't nested, follow the docs at https://docs.immich.app/errors#inconsistent-media-location to manually update stored paths or restore the database/volume consistently.
- Ensure database and uploaded files were moved together; a mismatch between DB paths and filesystem is the root cause.
- Use immich's provided migration tooling (migrate file paths) only when the new path starts with the old one.
Example fix
// before (docker-compose.yml) volumes: - /mnt/newlibrary:/usr/src/app/upload // after volumes: - /mnt/newlibrary/upload:/usr/src/app/upload # keeps external location consistent or nested under previous path
Defensive patterns
Strategy: try-catch
Validate before calling
// before startup, verify the configured media path is consistent with the database's stored location
const previous = await db.getSystemMetadataMediaLocation();
if (previous && !mediaPath.startsWith(previous)) throw new Error('Media location change is not a subpath; manual migration required'); Try / catch
try {
await startImmichServer();
} catch (e) {
if (/inconsistent media location/i.test(String(e.message))) {
// restore original mount path or follow docs.immich.app/errors#inconsistent-media-location
process.exit(1);
} else throw e;
} Prevention
- Keep the host-side mount path for the upload volume stable across deployments
- Move database and files together when relocating data
- If the path must change, make the new path a subpath of the old one so auto-migration works
- Consult docs.immich.app/errors#inconsistent-media-location before changing volumes
When it happens
Trigger: Changing the upload/data volume mount so the new external path is not nested under the old path (e.g. from /usr/src/app/upload to /mnt/library), then starting the server.
Common situations: Docker compose volume changes; moving from a bind mount to a different host directory; renaming the host folder; container image changes that relocate the internal upload path.
Related errors
- Failed to create
- Failed to read: " ( )
- Failed to write
- Asset dimensions are not available for editing
- Asset not in stack
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/e0dc682901346cdb.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/storage.service.ts:118
const savedValue = await this.systemMetadataRepository.get(SystemMetadataKey.MediaLocation);
if (samples.length > 0) {
const path = samples[0].path;
let previous = savedValue?.location || '';
if (!previous && this.configRepository.getEnv().storage.mediaLocation) {
previous = current;
}
if (!previous) {
previous = path.startsWith('upload/') ? 'upload' : '/usr/src/app/upload';
}
if (previous !== current) {
this.logger.log(`Media location changed (from=${previous}, to=${current})`);
if (!path.startsWith(previous)) {
throw new Error(ErrorMessages.InconsistentMediaLocation);
}
this.logger.warn(
`Detected a change to media location, performing an automatic migration of file paths from ${previous} to ${current}, this may take awhile`,
);
await this.databaseRepository.migrateFilePaths(previous, current);
}
}
// Only set MediaLocation in systemMetadataRepository if needed
if (savedValue?.location !== current) {
await this.systemMetadataRepository.set(SystemMetadataKey.MediaLocation, { location: current });
}
});
}
@OnJob({ name: JobName.FileDelete, queue: QueueName.BackgroundTask })
async handleDeleteFiles(job: JobOf<JobName.FileDelete>): Promise<JobStatus> {View on GitHub (pinned to e55ac299a4)