apache/cassandra · error · InvalidRequestException
Not-masking function
Error message
Not-masking function %s cannot be used for masking table columns
What it means
ColumnMask.findMaskingFunction rejects resolved native functions that are not instances of MaskingFunction. Only the built-in masking functions (mask_null, mask_default, mask_inner, mask_outer, hash) may be attached to columns; other native scalars like now(), toTimestamp(), or uuid() are disallowed.
Solutions
- Use one of the built-in masking functions: mask_null, mask_default, mask_inner, mask_outer, or hash.
- Create a scalar UDF in the same keyspace as the table and reference that instead.
Example fix
// before ALTER TABLE users ALTER created_at MASKED WITH now(); // after ALTER TABLE users ALTER created_at MASKED WITH mask_default(timestamp);
Defensive patterns
Strategy: validation
Validate before calling
Set<String> nativeMasks = Set.of("mask_null","mask_default","mask_inner","mask_outer","hash");
if (fnKeyspace == null && !nativeMasks.contains(fnName.toLowerCase()))
throw new IllegalArgumentException(fnName + " is not a masking function"); Prevention
- Treat the built-in masking function names as an exhaustive whitelist.
- Prefer UDFs for anything custom rather than repurposing native scalar functions.
When it happens
Trigger: MASKED WITH now() or any non-masking native function in CREATE TABLE / ALTER TABLE masked-column DDL.
Common situations: Developer tries to use an ordinary native scalar function as a masker, unaware that the whitelist is limited to MaskingFunction implementations (plus user-defined functions in the table's keyspace).
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
- Aggregate function cannot be used for masking table columns
- Altering field types is no longer supported
- Cannot use CREATE TABLE LIKE on a materialized view
- Cannot use CREATE TABLE LIKE on an index table
- Frozen UDT column does not support field deletions
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/dbadf424af155154.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/functions/masking/ColumnMask.java:253
private ScalarFunction findMaskingFunction(String keyspace, String table, ColumnIdentifier column, AbstractType<?> type, UserFunctions functions)
{
List<AssignmentTestable> args = new ArrayList<>(rawPartialArguments.size() + 1);
args.add(type);
args.addAll(rawPartialArguments);
Function function = FunctionResolver.get(keyspace, name, args, keyspace, table, type, functions);
if (function == null)
throw invalidRequest("Unable to find masking function for %s, " +
"no declared function matches the signature %s",
column, this);
if (function.isAggregate())
throw invalidRequest("Aggregate function %s cannot be used for masking table columns", this);
if (function.isNative() && !(function instanceof MaskingFunction))
throw invalidRequest("Not-masking function %s cannot be used for masking table columns", this);
if (!function.isNative() && !function.name().keyspace.equals(keyspace))
throw invalidRequest("Masking function %s doesn't belong to the same keyspace as the table %s.%s",
this, keyspace, table);
CQL3Type returnType = function.returnType().asCQL3Type();
CQL3Type expectedType = type.asCQL3Type();
if (!returnType.equals(expectedType))
throw invalidRequest("Masking function %s return type is %s. " +
"This is different to the type of the masked column %s of type %s. " +
"Masking functions can only be attached to table columns " +
"if they return the same data type as the masked column.",
this, returnType, column, expectedType);
return (ScalarFunction) function;
}
private ByteBuffer[] preparePartialArguments(String keyspace, ScalarFunction function)View on GitHub (pinned to 88fd0f6a0e)