apache/cassandra · error · InvalidRequestException

Function ' ' cannot replace an aggregate

Error message

Function '%s' cannot replace an aggregate

What it means

CREATE FUNCTION (without OR REPLACE semantics allowed) resolved an existing entity at the function's name/signature that is an aggregate, not a function. Cassandra keeps functions and aggregates in separate namespaces but shares the name; replacing an aggregate via CREATE FUNCTION is rejected to avoid accidentally overwriting an aggregate.

Solutions

  1. Pick a different name for the new function
  2. Drop the aggregate first with DROP AGGREGATE if it is no longer needed
  3. Note that OR REPLACE does not bypass this check - a name change or drop is required

Example fix

// before
CREATE OR REPLACE FUNCTION ks.avg(int) ...   -- ks.avg(int) is an aggregate
// after
DROP AGGREGATE IF EXISTS ks.avg(int);
CREATE FUNCTION ks.avg(int) ...
Defensive patterns

Strategy: validation

Validate before calling

ResultSet rs = session.execute("SELECT function_name FROM system_schema.aggregates WHERE keyspace_name = ? AND aggregate_name = ?", ks, fn);
if (!rs.all().isEmpty()) throw new IllegalStateException("Name collides with an aggregate: " + fn);

Try / catch

try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().contains("cannot replace an aggregate")) { /* rename function or drop aggregate */ } else throw e; }

Prevention

When it happens

Trigger: CREATE FUNCTION [IF NOT EXISTS] whose name and argument types match an existing aggregate created with CREATE AGGREGATE.

Common situations: Reusing an aggregate's name for a new function; migrations that create functions where aggregates previously existed; confusion between the function and aggregate namespaces.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/671db6514c6db47c. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateFunctionStatement.java:140

            rawArgumentTypes.stream()
                            .map(t -> t.prepare(keyspaceName, keyspace.types).getType().udfType())
                            .collect(toList());
        AbstractType<?> returnType = rawReturnType.prepare(keyspaceName, keyspace.types).getType().udfType();

        UDFunction function =
            UDFunction.create(new FunctionName(keyspaceName, functionName),
                              argumentNames,
                              argumentTypes,
                              returnType,
                              calledOnNullInput,
                              language,
                              body);

        UserFunction existingFunction = keyspace.userFunctions.find(function.name(), argumentTypes).orElse(null);
        if (null != existingFunction)
        {
            if (existingFunction.isAggregate())
                throw ire("Function '%s' cannot replace an aggregate", functionName);

            if (ifNotExists)
                return schema;

            if (!orReplace)
                throw ire("Function '%s' already exists", functionName);

            if (calledOnNullInput != ((UDFunction) existingFunction).isCalledOnNullInput())
            {
                throw ire("Function '%s' must have %s directive",
                          functionName,
                          calledOnNullInput ? "CALLED ON NULL INPUT" : "RETURNS NULL ON NULL INPUT");
            }

            if (!returnType.isCompatibleWith(existingFunction.returnType()))
            {
                throw ire("Cannot replace function '%s', the new return type %s is not compatible with the return type %s of existing function",
                          functionName,

View on GitHub (pinned to 88fd0f6a0e)