immich-app/immich · error · BadRequestException
Invalid backup name!
Error message
Invalid backup name!
What it means
Thrown by DatabaseBackupService.uploadBackup (BadRequestException). The uploaded file's basename must match /^\d\w.-]+\.sql(?:\.gz)?$/: only word characters, digits, hyphens and dots, ending in '.sql' or '.sql.gz'. Any other name is rejected before the file is written to the backups folder.
Source
Thrown at server/src/services/database-backup.service.ts:265
await this.storageRepository.rename(temporaryFilePath, backupFilePath);
} catch (error) {
this.logger.error(`Database Backup Failure: ${error}`);
await this.storageRepository
.unlink(temporaryFilePath)
.catch((error) => this.logger.error(`Failed to delete failed backup file: ${error}`));
throw error;
}
this.logger.log(`Database Backup Success`);
return backupFilePath;
}
async uploadBackup(file: Express.Multer.File): Promise<void> {
const backupsFolder = StorageCore.getBaseFolder(StorageFolder.Backups);
const fn = basename(file.originalname);
if (!isValidDatabaseBackupName(fn)) {
throw new BadRequestException('Invalid backup name!');
}
const filePath = path.join(backupsFolder, `uploaded-${fn}`);
await this.storageRepository.createOrOverwriteFile(filePath, file.buffer);
}
downloadBackup(fileName: string): ImmichFileResponse {
if (!isValidDatabaseBackupName(fileName)) {
throw new BadRequestException('Invalid backup name!');
}
const filePath = path.join(StorageCore.getBaseFolder(StorageFolder.Backups), fileName);
return {
path: filePath,
fileName,
cacheControl: CacheControl.PrivateWithoutCache,
contentType: fileName.endsWith('.gz') ? 'application/gzip' : 'application/sql',View on GitHub (pinned to 199723261c)
Solutions
- Rename the file to match <name>.sql.gz (or .sql), ASCII only, no spaces.
- If the file is gzipped, ensure the extension is exactly '.sql.gz'.
- Validate the filename client-side before upload using the same regex.
Example fix
// before
const fd = new FormData(); fd.append('file', rawFile); await upload(fd);
// after
const VALID = /^[\w\d.-]+\.sql(?:\.gz)?$/;
if (!VALID.test(rawFile.name)) {
throw new Error(`Backup filename must match ${VALID}`);
}
const fd = new FormData(); fd.append('file', rawFile); await upload(fd); Defensive patterns
Strategy: type-guard
Validate before calling
const VALID = /^[\w\d.-]+\.sql(?:\.gz)?$/;
if (!VALID.test(file.originalname)) {
throw new BadRequestException('Backup must be named <name>.sql or <name>.sql.gz');
} Type guard
function isValidBackupName(name: string): boolean {
return /^[\w\d.-]+\.sql(?:\.gz)?$/.test(name);
} Prevention
- Rename dumps to ASCII <name>.sql.gz before upload.
- Validate filenames client-side with the same regex.
- Avoid spaces, unicode, and non-sql extensions in backup names.
When it happens
Trigger: Uploading a backup whose original filename contains spaces, path separators, unusual extensions (e.g. .zip, .bak, .dump), or lacks the .sql/.sql.gz suffix.
Common situations: User renames a dump to something descriptive ('My Backup July.sql'); zipped/tarred dump (.zip); filename with spaces or unicode; case issues like '.SQL'.
Related errors
- Invalid backup file format!
- Invalid CLIP dimension size: ${dimSize}
- Unsupported file type ${filename}
- Quota has been exceeded!
- Unsupported PostgreSQL version: ${databaseVersion}
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/9e5a44a68f9049a7.
Report an issue: GitHub.