apache/cassandra · error · InvalidRequestException
Function ' ' is still referenced by column masks in tables
Error message
Function '%s' is still referenced by column masks in tables %s
What it means
DROP FUNCTION was rejected because the function is used as a column mask (dynamic data masking) on one or more tables. Cassandra refuses to drop functions still referenced by column masking definitions.
Solutions
- Remove the mask from the dependent columns first (ALTER TABLE ... ALTER col ... DROP MASKED or similar).
- Drop the listed tables if they are no longer needed.
- Then re-run DROP FUNCTION.
Example fix
// before DROP FUNCTION ks.mask_ssn (text); // after ALTER TABLE ks.users ALTER ssn DROP MASKED; DROP FUNCTION ks.mask_ssn (text);
Defensive patterns
Strategy: try-catch
Validate before calling
boolean masked = keyspace.tables.stream().anyMatch(t -> t.columns().stream()
.anyMatch(c -> c.mask() != null && c.mask().function().equals(fn)));
if (masked) unmaskColumnsFirst(); Try / catch
try { dropFunction(...); } catch (InvalidRequestException e) { if (e.getMessage().contains("referenced by column masks")) { /* unmask listed tables, then retry */ } else throw e; } Prevention
- Inventory column masks (system_schema.columns) before dropping functions
- Include unmasking in the function decommissioning runbook
- Prefix masking functions for easy traceability
When it happens
Trigger: DROP FUNCTION on a function referenced by a MASKED WITH column mask in any table of the keyspace; detected via keyspace.tablesUsingFunction(function).
Common situations: Forgetting to unmask column definitions before removing a masking function; security cleanup of masking functions while masking policies are still applied.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Argument ' ' cannot be frozen; remove frozen<> modifier from
- Function ' ' is still referenced by aggregates
- Masking function doesn't belong to the same keyspace as the…
- ACCESS TO DATACENTERS operations not supported by…
- Aggregate function cannot be used for masking table columns
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/c45b451ed8f96875.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/DropFunctionStatement.java:141
throw ire("Function '%s' doesn't exist", name);
}
String dependentAggregates =
keyspace.userFunctions
.aggregatesUsingFunction(function)
.map(a -> a.name().toString())
.collect(joining(", "));
if (!dependentAggregates.isEmpty())
throw ire("Function '%s' is still referenced by aggregates %s", name, dependentAggregates);
String dependentTables = keyspace.tablesUsingFunction(function)
.map(table -> table.name)
.collect(joining(", "));
if (!dependentTables.isEmpty())
throw ire("Function '%s' is still referenced by column masks in tables %s", name, dependentTables);
return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.userFunctions.without(function)));
}
SchemaChange schemaChangeEvent(KeyspacesDiff diff)
{
UserFunctions dropped = diff.altered.get(0).udfs.dropped;
assert dropped.size() == 1;
return SchemaChange.forFunction(Change.DROPPED, (UDFunction) dropped.iterator().next());
}
public void authorize(ClientState client)
{
KeyspaceMetadata keyspace = Schema.instance.getKeyspaceMetadata(keyspaceName);
if (null == keyspace)
return;
Stream<UserFunction> functions = keyspace.userFunctions.get(new FunctionName(keyspaceName, functionName)).stream();View on GitHub (pinned to 88fd0f6a0e)