The "DB::Exception: Backup is empty" error occurs when ClickHouse encounters a backup that contains no actual data. The BACKUP_IS_EMPTY error code is raised during a RESTORE operation when the backup exists at the specified location but has no tables, databases, or data parts to restore.
Impact
An empty backup provides no recovery value. If this is the backup you are counting on for disaster recovery, you effectively have no backup. The restore fails immediately, and you will need to locate an alternative backup or rebuild the data from other sources.
Common Causes
- Backing up an empty database -- running
BACKUP DATABASE my_dbon a database that has no tables or only empty tables. - Overly restrictive table filter -- using a
BACKUP TABLEcommand that matches no tables due to a typo or incorrect pattern. - Backup ran before data was loaded -- the backup job fired before the ingestion pipeline had inserted any data.
- Permissions issue -- the ClickHouse user executing the backup lacked
SELECTprivileges on the tables, so nothing was included. - Backup of temporary or view-only objects -- views and temporary tables do not contain data parts, so a backup targeting only these produces an empty result.
Troubleshooting and Resolution Steps
Check what the backup command targeted. Review the original
BACKUPstatement to see which databases or tables were included:BACKUP TABLE my_db.my_table TO Disk('backups', 'my_backup'); -- Was my_table actually populated at backup time?Verify the source has data:
SELECT database, table, sum(rows) AS total_rows, sum(bytes_on_disk) AS total_bytes FROM system.parts WHERE active GROUP BY database, table ORDER BY total_bytes DESC;Check for permission issues. Ensure the backup user has the required grants:
SHOW GRANTS FOR backup_user; -- Should include SELECT on the target tablesInspect the backup metadata to confirm it is truly empty:
ls -la /var/lib/clickhouse/backups/my_backup/ # An empty backup will have minimal metadata and no data directoriesRe-run the backup after confirming the source tables contain data:
BACKUP DATABASE my_db TO Disk('backups', 'my_backup_v2');Adjust backup scheduling so backups run after data ingestion completes, not before.
Best Practices
- Add post-backup validation that checks the backup size or entry count and raises an alert if the backup appears empty.
- Schedule backups at a time when you know data has been loaded, or add a dependency in your orchestration tool.
- Use explicit table names in backup commands rather than relying on database-level backups if only certain tables matter.
- Grant the backup user appropriate
SELECTprivileges and test the permissions before relying on automated backups. - Log the output of backup operations, including the number of tables and parts backed up, for audit purposes.
Frequently Asked Questions
Q: Why would a backup of a non-empty database be empty?
A: The most common reason is insufficient permissions. If the ClickHouse user running the backup cannot read the tables, no data is included. Another possibility is that the tables only contain data in materialized views or projections that the backup command did not target.
Q: Can I detect an empty backup without trying to restore it?
A: Yes. Check the system.backups table for the backup's total_size or num_entries fields. You can also inspect the backup directory on disk -- an empty backup will have minimal or no files under the data subdirectory.
Q: Does backing up a database with only views produce this error?
A: It can. Views do not store data parts, so a backup that only captures view definitions and no underlying tables may be considered empty. The backup will contain DDL statements but no data.
Q: How do I ensure my automated backups always capture data?
A: Add a pre-backup check in your script that queries system.parts to confirm the target tables have active parts. If they do not, skip the backup and alert your team.