immich-app/immich · error
Invalid backup file format!
Error message
Invalid backup file format!
What it means
restoreDatabaseBackup refuses to restore a file whose name does not pass isValidDatabaseBackupName, throwing before any filesystem or database work. This guards against restoring arbitrary/attacker-controlled paths. The raw Error is caught in the method's try/catch and triggers a rollback of the restore.
Solutions
- Restore only files that exist in the server's Backups storage folder with the original Immich-generated name (immich-dbBackup-*.sql.gz).
- Rename the file back to its original backup name before requesting restore.
- Verify the name with the same pattern locally: /^immich-dbBackup-.*\.sql\.gz$/ (or list backups via API and use returned names).
Example fix
// before
await api.restoreDatabaseBackup('my-dump.sql.gz');
// after
await api.restoreDatabaseBackup('immich-dbBackup-1700000000000.sql.gz'); Defensive patterns
Strategy: validation
Validate before calling
const BACKUP_NAME_RE = /^immich-dbBackup-.*\.sql\.gz$/;
if (!BACKUP_NAME_RE.test(filename)) throw new Error('Not a valid Immich backup file name'); Try / catch
try {
await api.restoreDatabaseBackup(filename);
} catch (e) {
if (/Invalid backup file format/.test(e.message)) {
console.error('Use a server-side backup file with its original name:', filename);
} else throw e;
} Prevention
- Keep the original immich-dbBackup-<ts>.sql.gz names when copying backups.
- Restore only files listed by the server's backups endpoint.
- Never pass paths or renamed dumps to the restore API.
When it happens
Trigger: POSTing a restore request with a filename that does not match the Immich database backup naming pattern (e.g. uploaded file renamed, or a path like '../../dump.sql').
Common situations: Users renaming .sql.gz dumps before upload; selecting the wrong file from the backups folder; crafted filenames for path traversal.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Server health check failed, no admin exists.
- Asset dimensions are not available for editing
- assetIds, albumId, or userId is required
- At least two people are required for merging
- Cannot add another owner
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/0f6358324769b132.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/database-backup.service.ts:370
toDelete.push(...failedBackups);
for (const file of toDelete) {
await this.storageRepository.unlink(path.join(backupsFolder, file));
}
this.logger.debug(`Database Backup Cleanup Finished, deleted ${toDelete.length} backups`);
}
async restoreDatabaseBackup(
filename: string,
progressCb?: (action: 'backup' | 'restore' | 'migrations' | 'rollback', progress: number) => void,
): Promise<void> {
this.logger.debug(`Database Restore Started`);
let isComplete = false;
try {
if (!isValidDatabaseBackupName(filename)) {
throw new Error('Invalid backup file format!');
}
const backupFilePath = path.join(StorageCore.getBaseFolder(StorageFolder.Backups), filename);
await this.storageRepository.stat(backupFilePath); // => check file exists
let isPgClusterDump = false;
const version = findDatabaseBackupVersion(filename);
if (version && satisfies(version, '<= 2.4')) {
isPgClusterDump = true;
}
const { bin, args, databaseUsername, databasePassword, databaseMajorVersion } =
await this.buildPostgresLaunchArguments('psql', {
singleTransaction: !isPgClusterDump,
});
progressCb?.('backup', 0.05);
View on GitHub (pinned to e55ac299a4)