apache/cassandra · error · InvalidRequestException

Non-frozen UDTs with nested non-frozen collections are not…

Error message

Non-frozen UDTs with nested non-frozen collections are not supported

What it means

A non-frozen (multi-cell) user-defined type whose fields themselves are multi-cell collections/UDTs cannot be used for a table column. Nested non-frozen types are unsupported in Cassandra's type system, so the builder rejects the column definition.

Solutions

  1. Freeze the UDT at the column definition: `col frozen<mytype>`
  2. Freeze the nested collection inside the UDT definition (e.g. `frozen<map<text,int>>`) so no field is multi-cell
  3. Restructure the schema to avoid nesting, using a separate table

Example fix

// before
CREATE TABLE ks.t (k int PRIMARY KEY, v my_udt); // my_udt has non-frozen collection field
// after
CREATE TABLE ks.t (k int PRIMARY KEY, v frozen<my_udt>);
Defensive patterns

Strategy: validation

Validate before calling

for each UDT column used unfrozen: if (udt.fieldTypes().stream().anyMatch(AbstractType::isMultiCell)) freeze the column as frozen<udt>;

Try / catch

try { session.execute(ddl); } catch (InvalidRequestException e) { if (e.getMessage().contains("Non-frozen UDTs with nested non-frozen collections")) { /* rewrite column as frozen<udt> */ } else throw e; }

Prevention

When it happens

Trigger: Declaring a column of a non-frozen UDT that contains a non-frozen collection field (e.g. `CREATE TYPE t (m map<text, int>); CREATE TABLE tb (... u frozen-free t ...)` where the UDT is used unfrozen).

Common situations: Modeling nested JSON-like structures in CQL; users expecting map/list fields inside UDTs to work like normal columns.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateTableStatement.java:282

    public TableMetadata.Builder builder(Types types, UserFunctions functions)
    {
        attrs.validate();
        TableParams params = attrs.asNewTableParams(keyspaceName);

        // use a TreeMap to preserve ordering across JDK versions (see CASSANDRA-9492) - important for stable unit tests
        Map<ColumnIdentifier, ColumnProperties> columns = new TreeMap<>(comparing(o -> o.bytes));
        rawColumns.forEach((column, properties) -> columns.put(column, properties.prepare(keyspaceName, tableName, column, types, functions)));

        // check for nested non-frozen UDTs or collections in a non-frozen UDT
        columns.forEach((column, properties) ->
        {
            AbstractType<?> type = properties.type;
            if (type.isUDT() && type.isMultiCell())
            {
                ((UserType) type).fieldTypes().forEach(field ->
                {
                    if (field.isMultiCell())
                        throw ire("Non-frozen UDTs with nested non-frozen collections are not supported");
                });
            }
        });

        /*
         * Deal with PRIMARY KEY columns
         */

        HashSet<ColumnIdentifier> primaryKeyColumns = new HashSet<>();
        concat(partitionKeyColumns, clusteringColumns).forEach(column ->
        {
            ColumnProperties properties = columns.get(column);
            if (null == properties)
                throw ire("Unknown column '%s' referenced in PRIMARY KEY for table '%s'", column, tableName);

            if (!primaryKeyColumns.add(column))
                throw ire("Duplicate column '%s' in PRIMARY KEY clause for table '%s'", column, tableName);

View on GitHub (pinned to 88fd0f6a0e)