immich-app/immich · error
Admin account does not exist
Error message
Admin account does not exist
What it means
The `resetAdminPassword` CLI command looks up the administrator account via userRepository.getAdmin() before prompting for a new password. If no admin account exists, it throws this plain Error, since resetting an admin password is meaningless without one. Typically indicates a corrupted or wiped user table.
Solutions
- Recreate the admin account (first registered user must be admin) before resetting its password.
- Check the database: SELECT * FROM "user" WHERE "isAdmin" = true; to confirm the admin row exists.
- Point the CLI at the correct database via environment variables — it may be connected to an empty/wrong DB.
- Restore the missing admin row from backup or re-run initial server setup.
Example fix
// before $ immich-admin reset-admin-password // throws: Admin account does not exist // after $ immich-admin create-user --admin # or create admin via setup wizard first $ immich-admin reset-admin-password
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify an admin exists before invoking the CLI reset
const admin = await db.query('SELECT id FROM "user" WHERE "isAdmin" = true LIMIT 1');
if (!admin.rows.length) throw new Error('Create the admin account first'); Try / catch
try {
await resetAdminPassword(promptFn);
} catch (e) {
if (e.message === 'Admin account does not exist') {
// bootstrap admin first, then retry
} else throw e;
} Prevention
- Never delete the admin row directly in SQL.
- Confirm the CLI's database connection env vars point at the live instance.
- Keep verified database backups that include the user table.
When it happens
Trigger: Running `immich-admin reset-admin-password` when no user row with isAdmin=true exists in the database.
Common situations: Database restored from a partial/old backup missing the admin row; admin user deleted via API or SQL; fresh database used with the admin CLI before initial setup.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- The first registered account must the administrator.
- User does not exist
- Album must have an owner
- await response.text()
- Column 'embedding' does not exist in table
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/b8e268656fc6112b.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/cli.service.ts:65
}
}
const drift = await this.databaseRepository.getSchemaDrift();
return { migrations, drift };
}
async listUsers(): Promise<UserAdminResponseDto[]> {
const users = await this.userRepository.getList({ withDeleted: true });
return users.map((user) => mapUserAdmin(user));
}
async resetAdminPassword(
ask: (admin: UserAdminResponseDto) => Promise<{ newPassword: string | undefined; invalidateSessions: boolean }>,
) {
const admin = await this.userRepository.getAdmin();
if (!admin) {
throw new Error('Admin account does not exist');
}
const { newPassword: providedPassword, invalidateSessions } = await ask(mapUserAdmin(admin));
const password = providedPassword || this.cryptoRepository.randomBytesAsText(24);
const hashedPassword = await this.cryptoRepository.hashBcrypt(password, SALT_ROUNDS);
await this.userRepository.update(admin.id, { password: hashedPassword });
if (invalidateSessions) {
await this.sessionRepository.invalidateAll({ userId: admin.id });
}
return { admin, password, provided: !!providedPassword };
}
async disablePasswordLogin(): Promise<void> {
const config = await this.getConfig({ withCache: false });
config.passwordLogin.enabled = false;View on GitHub (pinned to e55ac299a4)