The "DB::Exception: Cannot drop function" error in ClickHouse appears when you attempt to drop a user-defined function (UDF) and the operation cannot be completed. This might happen because the function does not exist, it is a built-in function, or there are dependency or permission issues. The error code is CANNOT_DROP_FUNCTION.
Impact
The DROP FUNCTION statement fails, and the function remains registered. This is a non-destructive failure. However, if you need to drop the function as part of a migration or cleanup process, your workflow will be blocked until the issue is resolved.
Common Causes
- Function does not exist -- attempting to drop a UDF that was never created or was already dropped.
- Trying to drop a built-in function -- built-in ClickHouse functions cannot be dropped.
- Insufficient permissions -- the user does not have the privilege to drop functions.
- Function is in use by a materialized view or other object -- while ClickHouse does not always enforce this, dependency conflicts can arise.
- Cluster synchronization issues -- on a cluster, the function may have been dropped on some nodes but not others.
Troubleshooting and Resolution Steps
Check if the function exists and is user-defined:
SELECT name, origin FROM system.functions WHERE name = 'your_function_name';If
originis notSQLUserDefined, it is a built-in function and cannot be dropped.Use IF EXISTS to avoid errors when the function may not exist:
DROP FUNCTION IF EXISTS your_function_name;Check your permissions. Verify you have the necessary privileges:
SHOW GRANTS FOR CURRENT_USER;You need the
DROP FUNCTIONprivilege or the broaderCREATE FUNCTIONprivilege (which typically covers DROP as well).On a cluster, ensure consistency. Drop the function on all nodes:
DROP FUNCTION IF EXISTS your_function_name ON CLUSTER 'your_cluster';Check for dependencies. If the function is referenced by a materialized view or another UDF, you may need to drop or alter the dependent object first:
-- Search for references to the function SELECT name, create_table_query FROM system.tables WHERE create_table_query LIKE '%your_function_name%';Verify the function file on disk. UDFs are stored in the
user_defineddirectory within the ClickHouse data path. If the metadata is corrupted, you may need to remove the file manually and restart the server (as a last resort).
Best Practices
- Always use
DROP FUNCTION IF EXISTSin scripts to make them idempotent and avoid failures on repeated runs. - Use
ON CLUSTERfor DROP FUNCTION on distributed setups to maintain consistency across nodes. - Before dropping a UDF, search for dependencies in materialized views, other UDFs, and application queries.
- Maintain version-controlled UDF definitions so dropped functions can be easily recreated if needed.
- Restrict DROP FUNCTION privileges to administrators to prevent accidental removal of shared functions.
Frequently Asked Questions
Q: Can I drop a built-in ClickHouse function?
A: No. Built-in functions are part of the ClickHouse binary and cannot be dropped. Only user-defined functions (created with CREATE FUNCTION) can be dropped.
Q: What happens if I drop a UDF that is used in a materialized view?
A: ClickHouse may allow the drop, but subsequent INSERTs into the materialized view's source table will fail because the function no longer exists. Always check for dependencies before dropping a UDF.
Q: How do I drop and recreate a function atomically?
A: Use CREATE OR REPLACE FUNCTION instead of a DROP followed by CREATE. This avoids a window where the function is missing.
Q: The function file exists on disk but DROP FUNCTION still fails. What should I do?
A: This may indicate metadata corruption. As a last resort, stop ClickHouse, remove the function's XML or SQL file from the user_defined directory in the ClickHouse data path, and restart the server. Always back up before manual file operations.