apache/cassandra · error · InvalidRequestException

Aggregate ' ' already exists

Error message

Aggregate '%s' already exists

What it means

Thrown when CREATE AGGREGATE targets a signature for which an aggregate already exists, IF NOT EXISTS was not specified, and OR REPLACE was not specified. Cassandra refuses to silently overwrite an existing aggregate.

Solutions

  1. Add IF NOT EXISTS to skip creation when the aggregate already exists.
  2. Add OR REPLACE to overwrite the existing aggregate.
  3. DROP AGGREGATE the existing one first if you want a clean create.
  4. Check existing definitions with DESC AGGREGATE or system_schema.functions.

Example fix

// before
CREATE AGGREGATE ks.avg(int) SFUNC s STYPE int FINALFUNC f;
// after
CREATE AGGREGATE IF NOT EXISTS ks.avg(int) SFUNC s STYPE int FINALFUNC f;
Defensive patterns

Strategy: validation

Validate before calling

var existing = keyspace.userFunctions.find(fnName, argTypes);
boolean skip = existing.isPresent() && existing.get().isAggregate() && useIfNotExists;
if (existing.isPresent() && !useIfNotExists && !useOrReplace)
    throw new IllegalStateException(fnName + " already exists; use IF NOT EXISTS or OR REPLACE");

Try / catch

try { session.execute(ddl); }
catch (InvalidRequestException e) {
    if (e.getMessage().contains("already exists")) { /* rerun with IF NOT EXISTS / OR REPLACE */ }
    else throw e;
}

Prevention

When it happens

Trigger: Re-running CREATE AGGREGATE for an existing (name, argumentTypes) signature without IF NOT EXISTS or OR REPLACE.

Common situations: Idempotent migration scripts re-executed against an existing schema; accidental duplicate DDL from parallel tooling.

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/717c423f2db89883. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java:229

        UDAggregate aggregate =
            new UDAggregate(new FunctionName(keyspaceName, aggregateName),
                            argumentTypes,
                            returnType,
                            (ScalarFunction) stateFunction,
                            (ScalarFunction) finalFunction,
                            initialValue);

        UserFunction existingAggregate = keyspace.userFunctions.find(aggregate.name(), argumentTypes).orElse(null);
        if (null != existingAggregate)
        {
            if (!existingAggregate.isAggregate())
                throw ire("Aggregate '%s' cannot replace a function", aggregateName);

            if (ifNotExists)
                return schema;

            if (!orReplace)
                throw ire("Aggregate '%s' already exists", aggregateName);

            if (!returnType.isCompatibleWith(existingAggregate.returnType()))
            {
                throw ire("Cannot replace aggregate '%s', the new return type %s isn't compatible with the return type %s of existing function",
                          aggregateName,
                          returnType.asCQL3Type(),
                          existingAggregate.returnType().asCQL3Type());
            }
        }

        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.userFunctions.withAddedOrUpdated(aggregate)));
    }

    private static boolean isNullOrEmpty(AbstractType<?> type, ByteBuffer bb)
    {
        return bb == null ||
               (bb.remaining() == 0 && type.isEmptyValueMeaningless());
    }

View on GitHub (pinned to 88fd0f6a0e)