The "DB::Exception: Table is dropped" error appears when you try to access a table that is currently being dropped or has already been marked for removal. ClickHouse raises this with the error code TABLE_IS_DROPPED. It is a transient condition in most cases -- the table exists in metadata but is no longer available for queries because a DROP operation is in progress or has completed but cleanup is not yet finished.
Impact
All queries targeting the dropped table will fail immediately with this error. This includes SELECT, INSERT, and ALTER statements. If your application retries queries aggressively, you may see a burst of these errors until the drop completes and the table name fully disappears from the system catalog.
Common Causes
- Concurrent access during a DROP TABLE operation -- a query hits the table while another session is dropping it.
- Slow drop of a large table -- dropping tables with many parts can take time, and during that window the table is in a "dropped" state.
- Replicated table drop propagation -- in a cluster, the drop may be applied on one replica while another is still serving queries.
- Application not handling table lifecycle -- the application assumes the table always exists without checking.
- Race condition in migration scripts -- a script drops and recreates a table, and concurrent queries arrive between the drop and the create.
Troubleshooting and Resolution Steps
Wait and retry. If the table is being dropped intentionally, this error is transient. A short retry with backoff will resolve it once the drop completes and the table is either gone or recreated.
Check whether the drop was intentional:
SELECT query, event_time, user FROM system.query_log WHERE query LIKE '%DROP TABLE%' ORDER BY event_time DESC LIMIT 10;If the table should still exist, check
system.tables:SELECT database, name, engine, metadata_modification_time FROM system.tables WHERE name = 'my_table';An empty result means the table is fully gone.
For replicated tables, check ZooKeeper state. The table may still have metadata in ZooKeeper even if it has been dropped locally:
SELECT * FROM system.zookeeper WHERE path = '/clickhouse/tables/my_table';If a migration script is causing the issue, add a pause or check between DROP and CREATE:
DROP TABLE IF EXISTS my_table SYNC; -- The SYNC keyword ensures the drop completes before proceeding CREATE TABLE my_table (...) ENGINE = MergeTree() ORDER BY id;Review application retry logic. Make sure your application can gracefully handle this transient error by retrying after a brief delay.
Best Practices
- Use
DROP TABLE ... SYNCin migration scripts to ensure the drop is fully complete before executing subsequent statements. - Implement retry logic with exponential backoff in applications that may encounter table lifecycle changes.
- Coordinate table drops across teams -- use a maintenance window or notify dependent services.
- In clustered environments, use
ON CLUSTERfor DROP statements and allow time for propagation. - Avoid dropping and immediately recreating tables in high-traffic environments; consider using
RENAME TABLEorEXCHANGE TABLESinstead.
Frequently Asked Questions
Q: Is this error permanent or transient?
A: It is almost always transient. Once the DROP operation completes (or the table is recreated), the error will stop. If you see it persistently, the table metadata may be in a corrupted state.
Q: What does DROP TABLE ... SYNC do?
A: The SYNC keyword forces ClickHouse to wait until all parts of the table are physically removed before returning. Without it, the drop happens asynchronously and the table enters a "dropped" state while cleanup continues in the background.
Q: Can I recover a table that is in the "dropped" state?
A: If the drop has not fully completed, there is no built-in way to cancel it. However, if you are using the Atomic database engine, recently dropped tables can be recovered using UNDROP TABLE (available in ClickHouse 23.3+).
Q: How do I avoid this error in a busy production environment?
A: Minimize direct DROP TABLE operations on tables with active queries. Use EXCHANGE TABLES to atomically swap a new table in place of the old one, which avoids the window where the table is unavailable.