apache/cassandra · error · InvalidRequestException

Non-frozen UDTs are not allowed inside collections:

Error message

Non-frozen UDTs are not allowed inside collections: 

What it means

InvalidRequestException (via throwNestedNonFrozenError) raised while preparing a collection type whose elements include a non-frozen user-defined type. Only frozen UDTs may appear inside collections; the check triggers when the value type supports freezing but was left unfrozen.

Source

Thrown at src/java/org/apache/cassandra/cql3/CQL3Type.java:899

                switch (kind)
                {
                    case LIST:
                        return new Collection(ListType.getInstance(valueType, !frozen));
                    case SET:
                        return new Collection(SetType.getInstance(valueType, !frozen));
                    case MAP:
                        assert keys != null : "Got null keys type for a collection";
                        return new Collection(MapType.getInstance(keys.prepare(keyspace, udts).getType(), valueType, !frozen));
                }
                throw new AssertionError();
            }

            private void throwNestedNonFrozenError(Raw innerType)
            {
                if (innerType instanceof RawCollection)
                    throw new InvalidRequestException("Non-frozen collections are not allowed inside collections: " + this);
                else if (innerType.isUDT())
                    throw new InvalidRequestException("Non-frozen UDTs are not allowed inside collections: " + this);
            }

            public boolean referencesUserType(String name)
            {
                return (keys != null && keys.referencesUserType(name)) || values.referencesUserType(name);
            }

            @Override
            public String toString()
            {
                String start = frozen? "frozen<" : "";
                String end = frozen ? ">" : "";
                switch (kind)
                {
                    case LIST: return start + "list<" + values + '>' + end;
                    case SET:  return start + "set<" + values + '>' + end;
                    case MAP:  return start + "map<" + keys + ", " + values + '>' + end;
                }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Wrap the UDT in frozen<>: `list<frozen<address>>`
  2. Freeze the UDT at definition time (`CREATE TYPE ... ` then use frozen<address> everywhere it is nested)
  3. Restructure into a separate table if per-field updates on nested UDTs are needed

Example fix

// before
CREATE TABLE t (id uuid PRIMARY KEY, addresses list<address>);
// after
CREATE TABLE t (id uuid PRIMARY KEY, addresses list<frozen<address>>);
Defensive patterns

Strategy: validation

Validate before calling

boolean hasNonFrozenUdtInCollection(String typeDecl, java.util.Set<String> udtNames) {
    String s = typeDecl.toLowerCase();
    return udtNames.stream().anyMatch(u -> s.matches(".*<(?!frozen\\s*<)" + u + "[>,].*"));
}

Try / catch

try { session.execute(ddl); } catch (InvalidQueryException e) { if (e.getMessage().startsWith("Non-frozen UDTs are not allowed inside collections")) { /* use frozen<udt> inside collections */ } else throw e; }

Prevention

When it happens

Trigger: Declaring e.g. `list<address>` or `map<text, address>` where `address` is a UDT declared without frozen<> in CREATE TABLE / ALTER TABLE.

Common situations: Common when first using UDTs in Cassandra — developers forget frozen is mandatory for UDTs inside collections.

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/6f71bfb0e4aa16d0. Report an issue: GitHub.