apache/cassandra · error · InvalidRequestException

State type ' ' cannot be frozen; remove frozen<> modifier…

Error message

State type '%s' cannot be frozen; remove frozen<> modifier from '%s'

What it means

CREATE AGGREGATE guard rejecting a frozen state type. The state function's accumulator type must be non-frozen, so a state type declared with frozen<> is rejected since aggregates mutate their state in place.

Solutions

  1. Remove frozen<> from STYPE in the CREATE AGGREGATE statement
  2. Declare STYPE as the unfrozen type, e.g. STYPE map<text,int>
  3. Re-check any DDL generator emitting frozen<> for function/aggregate types

Example fix

// before
CREATE AGGREGATE ks.sum(map<text,int>) STYPE frozen<map<text,int>> ...
// after
CREATE AGGREGATE ks.sum(map<text,int>) STYPE map<text,int> ...
Defensive patterns

Strategy: validation

Validate before calling

if (stateType.contains("frozen<") && !isImplicitlyFrozen(stateType))
    throw new IllegalArgumentException("Remove frozen<> from STYPE: " + stateType);

Try / catch

try { session.execute(ddl); }
catch (InvalidRequestException e) { if (e.getMessage().contains("State type") && e.getMessage().contains("cannot be frozen")) retryWithUnfrozenStype(ddl); else throw e; }

Prevention

When it happens

Trigger: rawStateType.isFrozen() && !rawStateType.isImplicitlyFrozen() in CreateAggregateStatement.apply, i.e. STYPE written as frozen<...>.

Common situations: Declaring STYPE frozen<map<text,int>> because table schemas required frozen maps; generated DDL carrying frozen modifiers over from column types.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

        return metadata.directory.commonSerializationVersion.isAtLeast(Version.V0);
    }

    @Override
    public Keyspaces apply(ClusterMetadata metadata)
    {
        if (ifNotExists && orReplace)
            throw ire("Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives");

        if (!FunctionName.isNameValid(aggregateName))
            throw ire("Aggregate name '%s' is invalid", aggregateName);

        rawArgumentTypes.stream()
                        .filter(raw -> !raw.isImplicitlyFrozen() && raw.isFrozen())
                        .findFirst()
                        .ifPresent(t -> { throw ire("Argument '%s' cannot be frozen; remove frozen<> modifier from '%s'", t, t); });

        if (!rawStateType.isImplicitlyFrozen() && rawStateType.isFrozen())
            throw ire("State type '%s' cannot be frozen; remove frozen<> modifier from '%s'", rawStateType, rawStateType);

        Keyspaces schema = metadata.schema.getKeyspaces();
        KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);
        if (null == keyspace)
            throw ire("Keyspace '%s' doesn't exist", keyspaceName);

        /*
         * Resolve the state function
         */

        List<AbstractType<?>> argumentTypes =
            rawArgumentTypes.stream()
                            .map(t -> t.prepare(keyspaceName, keyspace.types).getType().udfType())
                            .collect(toList());
        AbstractType<?> stateType = rawStateType.prepare(keyspaceName, keyspace.types).getType().udfType();
        List<AbstractType<?>> stateFunctionArguments = Lists.newArrayList(concat(singleton(stateType), argumentTypes));

        UserFunction stateFunction =

View on GitHub (pinned to 88fd0f6a0e)