immich-app/immich · error
Server health check failed, no admin exists.
Error message
Server health check failed, no admin exists.
What it means
After restoring a database backup, the service runs migrations and then performs a health check that requires at least one admin user to exist. If userRepository.hasAdmin() returns false, the restore is considered failed (thrown inside the try block, so a rollback is triggered) because a backup without an admin account cannot produce a usable server.
Solutions
- Restore a backup taken from a fully initialized Immich instance (setup completed, admin created).
- Register an admin user after restore, or re-restore with a complete backup.
- Verify the dump includes the users table with an admin entry before restoring.
Defensive patterns
Strategy: try-catch
Validate before calling
const users = await api.getAllUsers();
if (!users.some((u) => u.isAdmin)) throw new Error('Backup has no admin user; restore would fail'); Try / catch
try {
await api.restoreDatabaseBackup(filename);
} catch (e) {
if (/no admin exists/.test(e.message)) {
console.error('Backup predates admin creation; restore a complete backup and re-run setup.');
} else throw e;
} Prevention
- Only back up instances that have completed initial setup (admin registered).
- After any restore, verify an admin user exists before relying on the server.
- Avoid hand-edited or partial SQL dumps for restore.
When it happens
Trigger: Restoring a database dump that contains no admin user — e.g. a backup taken before initial setup, an empty/partial dump, or a dump from a fresh database where migrations ran but the setup wizard was never completed.
Common situations: Restoring backups copied from another instance's pre-setup state; manually imported SQL dumps; backups from test environments with no registered user.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/019628975cfc3f82.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/database-backup.service.ts:429
const [progressSource, progressSink] = createSqlProgressStreams((progress) => {
if (isComplete) {
return;
}
this.logger.log(`Restore progress ~ ${(progress * 100).toFixed(2)}%`);
progressCb?.('restore', progress);
});
await pipeline(sqlStream, createSqlOwnerTransformStream(databaseUsername), progressSource, psql, progressSink);
try {
progressCb?.('migrations', 0.9);
await this.databaseRepository.runMigrations();
const hasAdmin = await this.userRepository.hasAdmin();
if (!hasAdmin) {
throw new Error('Server health check failed, no admin exists.');
}
await this.maintenanceHealthRepository.checkApiHealth();
} catch (error) {
progressCb?.('rollback', 0);
const fileStream = this.storageRepository.createPlainReadStream(restorePointFilePath);
const gunzip = this.storageRepository.createGunzip();
fileStream.pipe(gunzip);
inputStream = gunzip;
const sqlStream = Readable.from(sqlRollback(inputStream, databaseUsername));
const psql = this.processRepository.spawnDuplexStream(bin, args, {
env: {
PATH: process.env.PATH,
PGPASSWORD: databasePassword,
},
});View on GitHub (pinned to e55ac299a4)