apache/cassandra · error · InvalidRequestException

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

Error message

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

What it means

A CREATE FUNCTION statement declared a frozen< > return type, which Cassandra rejects. Function return types must be non-frozen; the statement validates the raw return type is not explicitly frozen before preparing it.

Solutions

  1. Remove frozen<> from the RETURNS clause
  2. Declare the return type without the frozen modifier, e.g. RETURNS list<int>
  3. Keep frozen<> only where table schemas require it

Example fix

// before
CREATE FUNCTION ks.f() RETURNS frozen<list<int>> ...
// after
CREATE FUNCTION ks.f() RETURNS list<int> ...
Defensive patterns

Strategy: validation

Validate before calling

if (!rawReturnType.isImplicitlyFrozen() && rawReturnType.isFrozen()) throw new IllegalArgumentException("Remove frozen<> from return type");

Type guard

boolean isFrozenReturn(CQLType raw) { return !raw.isImplicitlyFrozen() && raw.isFrozen(); }

Try / catch

try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().startsWith("Return type") && e.getMessage().contains("frozen")) { /* fix RETURNS clause */ } else throw e; }

Prevention

When it happens

Trigger: CREATE FUNCTION whose RETURNS clause uses frozen<...>, e.g. RETURNS frozen<list<int>>.

Common situations: Copy-pasting a frozen column type into the RETURNS clause; authoring UDFs that mirror table schema types verbatim.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

    {
        if (ifNotExists && orReplace)
            throw ire("Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives");

        UDFunction.assertUdfsEnabled(language);

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

        if (new HashSet<>(argumentNames).size() != argumentNames.size())
            throw ire("Duplicate argument names for given function %s with argument names %s", functionName, argumentNames);

        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 (!rawReturnType.isImplicitlyFrozen() && rawReturnType.isFrozen())
            throw ire("Return type '%s' cannot be frozen; remove frozen<> modifier from '%s'", rawReturnType, rawReturnType);

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

        List<AbstractType<?>> argumentTypes =
            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,

View on GitHub (pinned to 88fd0f6a0e)