apache/cassandra · error · InvalidRequestException
Non-frozen UDTs with nested non-frozen collections are not s
Error message
Non-frozen UDTs with nested non-frozen collections are not supported for column <name>
What it means
A non-frozen user-defined type (UDT) may not contain fields whose types are themselves multi-cell (non-frozen collections such as list/map/set, or nested non-frozen UDTs). Cassandra requires such nested multi-cell fields to be frozen. The check runs when adding (or altering to add) a column whose declared type is a non-frozen UDT with at least one multi-cell field.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java:375
return;
}
if (type.isCounter() && (table.params.transactionalMode.accordIsEnabled || table.params.transactionalMigrationFrom.migratingFromAccord()))
throw ire(format(ACCORD_COUNTER_COLUMN_UNSUPPORTED, keyspaceName, tableName, table.params.transactionalMode, table.params.transactionalMigrationFrom));
if (table.isCompactTable())
throw ire("Cannot add new column to a COMPACT STORAGE table");
if (isStatic && table.clusteringColumns().isEmpty())
throw ire("Static columns are only useful (and thus allowed) if the table has at least one clustering column");
// check for nested non-frozen UDTs or collections in a non-frozen UDT
if (type.isUDT() && type.isMultiCell())
{
for (AbstractType<?> fieldType : ((UserType) type).fieldTypes())
{
if (fieldType.isMultiCell())
throw ire("Non-frozen UDTs with nested non-frozen collections are not supported for column " + column.name);
}
}
ColumnMetadata droppedColumn = table.getDroppedColumn(name.bytes);
if (null != droppedColumn)
{
// After #8099, not safe to re-add columns of incompatible types - until *maybe* deser logic with dropped
// columns is pushed deeper down the line. The latter would still be problematic in cases of schema races.
if (!type.isSerializationCompatibleWith(droppedColumn.type))
{
throw ire("Cannot add a column '%s' of type %s, incompatible with previously dropped column '%s' of type %s",
name,
type.asCQL3Type(),
name,
droppedColumn.type.asCQL3Type());
}
if (droppedColumn.isStatic() != isStatic)View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Freeze the nested collection inside the UDT: ALTER TYPE address ADD tags frozen<list<text>>; or redefine the type with frozen collection fields.
- Freeze the whole column instead: ALTER TABLE t ADD col frozen<address> (note frozen values are overwritten as a whole, no partial updates).
- Restructure the UDT to hold only primitives or frozen types.
- If nesting is genuinely needed, model the nested data as a separate table keyed by the parent partition key.
Example fix
// before CREATE TYPE address (tags list<text>); ALTER TABLE users ADD addr address; -- fails: nested non-frozen list // after CREATE TYPE address (tags frozen<list<text>>); ALTER TABLE users ADD addr address; -- or: ADD addr frozen<address>
Defensive patterns
Strategy: validation
Validate before calling
// before adding a UDT column, inspect its fields
UserType udt = (UserType) keyspace.types.get(udtName).getType();
if (!udt.isFrozen() && java.util.Arrays.stream(udt.fieldTypes()).anyMatch(AbstractType::isMultiCell))
throw new IllegalArgumentException("UDT " + udtName + " contains non-frozen collections; freeze fields or freeze the column."); Type guard
boolean udtAddable(AbstractType<?> t) {
return !(t.isUDT() && t.isMultiCell()
&& java.util.Arrays.stream(((UserType) t).fieldTypes()).anyMatch(AbstractType::isMultiCell));
} Try / catch
try {
session.execute("ALTER TABLE t ADD col " + udtName);
} catch (InvalidQueryException e) {
if (e.getMessage().contains("nested non-frozen collections")) {
session.execute("ALTER TABLE t ADD col frozen<" + udtName + ">>");
} else throw e;
} Prevention
- Define UDT fields as frozen<list<...>>/frozen<map<...>> whenever nesting is required.
- Audit UDT definitions with system_schema.types before referencing them in ALTER statements.
- Remember frozen columns forbid partial field updates — design accordingly before freezing.
- Keep UDTs flat (primitive fields only) when non-frozen usage is intended.
When it happens
Trigger: ALTER TABLE t ADD col <udt_name> where udt_name resolves to a UserType with isMultiCell()==true (non-frozen) that has any field type which is itself a non-frozen collection or non-frozen nested UDT.
Common situations: Declaring CREATE TYPE address (tags list<text>, phones map<text,text>) and then adding it unfrozen; upgrading schemas from older versions where such nesting was inconsistently handled; ORM/model generators emitting nested collections inside UDTs.
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
- Non-frozen UDTs are not allowed inside collections:
- Constraint cannot be defined on the column <name> of type <t
- frozen<> is only allowed on collections, tuples, and user-de
- Non-frozen collections are not allowed inside collections:
- Statement on keyspace %s cannot refer to a user type in keys
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/54c43743d2f3f48d.
Report an issue: GitHub.