apache/cassandra · error · InvalidRequestException

A user type cannot contain non-frozen UDTs

Error message

A user type cannot contain non-frozen UDTs

What it means

Validation guard in CreateTypeStatement.apply() fired during CREATE TYPE: a field's type resolves to a user-defined type that is not frozen. Since non-frozen UDTs cannot be nested inside another UDT (their inner fields would not be updateable in place), the statement is rejected with InvalidRequestException before any schema mutation.

Solutions

  1. Declare the nested UDT field as frozen, e.g. frozen<other_type>, in the CREATE TYPE statement; flatten the nested type into the outer type if freezing is not desired; create the inner type already frozen at its own definition if the schema design permits.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateTypeStatement.java:115 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateTypeStatement.java:115

        {
            if (ifNotExists)
                return schema;

            throw ire("A user type with name '%s' already exists", typeName);
        }

        Set<FieldIdentifier> usedNames = new HashSet<>();
        for (FieldIdentifier name : fieldNames)
            if (!usedNames.add(name))
                throw ire("Duplicate field name '%s' in type '%s'", name, typeName);

        for (CQL3Type.Raw type : rawFieldTypes)
        {
            if (type.isCounter())
                throw ire("A user type cannot contain counters");

            if (type.isUDT() && !type.isFrozen())
                throw ire("A user type cannot contain non-frozen UDTs");
        }

        List<AbstractType<?>> fieldTypes =
            rawFieldTypes.stream()
                         .map(t -> t.prepare(keyspaceName, keyspace.types).getType())
                         .collect(toList());

        UserType udt = new UserType(keyspaceName, bytes(typeName), fieldNames, fieldTypes, true);
        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.types.with(udt)));
    }

    SchemaChange schemaChangeEvent(KeyspacesDiff diff)
    {
        return new SchemaChange(Change.CREATED, Target.TYPE, keyspaceName, typeName);
    }

    public void authorize(ClientState client)
    {

View on GitHub (pinned to 88fd0f6a0e)