apache/cassandra · error · InvalidRequestException
Cannot add new field %s of type %s to user type %s as the ty
Error message
Cannot add new field %s of type %s to user type %s as the type is being used in partition key by the following tables: %s
What it means
Cassandra refuses to add a field to a UDT that is used (unfrozen) in any table's partition key, because changing the type would change partition key serialization and make existing rows unreachable. AddField.apply enumerates tables and views whose partition key columns reference the UDT and rejects the ALTER with the list of offending tables.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTypeStatement.java:162
if (type.isUDT() && !type.isFrozen())
throw ire("A user type cannot contain non-frozen UDTs");
if (userType.fieldPosition(fieldName) >= 0)
{
if (!ifFieldNotExists)
throw ire("Cannot add field %s to type %s: a field with name %s already exists", fieldName, userType.getCqlTypeName(), fieldName);
return userType;
}
AbstractType<?> fieldType = type.prepare(keyspaceName, keyspace.types).getType();
if (fieldType.referencesUserType(userType.name))
throw ire("Cannot add new field %s of type %s to user type %s as it would create a circular reference", fieldName, type, userType.getCqlTypeName());
Collection<TableMetadata> tablesWithTypeInPartitionKey = findTablesReferencingTypeInPartitionKey(keyspace, userType);
if (!tablesWithTypeInPartitionKey.isEmpty())
{
throw ire("Cannot add new field %s of type %s to user type %s as the type is being used in partition key by the following tables: %s",
fieldName, type, userType.getCqlTypeName(),
String.join(", ", transform(tablesWithTypeInPartitionKey, TableMetadata::toString)));
}
Guardrails.fieldsPerUDT.guard(userType.size() + 1, userType.getNameAsString(), false, state);
type.validate(state, "Field " + fieldName);
List<FieldIdentifier> fieldNames = new ArrayList<>(userType.fieldNames()); fieldNames.add(fieldName);
List<AbstractType<?>> fieldTypes = new ArrayList<>(userType.fieldTypes()); fieldTypes.add(fieldType);
return new UserType(keyspaceName, userType.name, fieldNames, fieldTypes, true);
}
private static Collection<TableMetadata> findTablesReferencingTypeInPartitionKey(KeyspaceMetadata keyspace, UserType userType)
{
Collection<TableMetadata> tables = new ArrayList<>();
filter(keyspace.tablesAndViews(),
table -> any(table.partitionKeyColumns(), column -> column.type.referencesUserType(userType.name)))View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Drop and recreate dependent tables without the UDT in the partition key, add the field, then recreate/repopulate the data
- Create a new table with a different design (e.g. freeze the UDT or move it to a regular column), migrate data, drop the old table
- Use a new UDT version (e.g. addr_v2) for the new schema and migrate tables away from the old type
Example fix
// before CREATE TABLE events (k frozen<addr>, ... PRIMARY KEY ((k), ts)); -- still blocks add -- after: move UDT out of partition key CREATE TABLE events (id uuid, k addr, ..., PRIMARY KEY (id, ts));
Defensive patterns
Strategy: validation
Validate before calling
// Before altering a UDT, check partition-key usage:
ResultSet rs = session.execute("SELECT table_name, column_name FROM system_schema.columns " +
"WHERE keyspace_name='myks' AND kind='partition_key'");
// verify none of the partition key column types reference the UDT before ALTER TYPE ... ADD Try / catch
try { session.execute(alterTypeCql); }
catch (InvalidQueryException e) {
if (e.getMessage().contains("used in partition key")) { /* migrate tables listed in the message first */ }
else throw e;
} Prevention
- Avoid unfrozen UDTs in partition keys; keep partition keys on primitives (uuid, text, int)
- Query system_schema.columns for partition_key columns referencing the UDT before any ALTER TYPE
- Plan UDT evolution before creating tables that use the type in keys
When it happens
Trigger: `ALTER TYPE myks.addr ADD zip text` where some table was created with `PRIMARY KEY ((addr), ...)` containing the addr UDT unfrozen in the partition key.
Common situations: UDTs accidentally placed in partition keys early in design, then needing evolution later; multi-DC migrations where schema drift re-introduced the UDT into a partition key.
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
- Cannot add new field %s of type %s to user type %s as it wou
- category %s not found in %s
- 'Get CIDR groups for IP' operation not supported by %s
- ACCESS TO DATACENTERS operations not supported by AllowAllNe
- Not enough bytes to read size of %dth field %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/6067b70bf1ae44e9.
Report an issue: GitHub.