apache/cassandra · error · InvalidRequestException

Cannot drop user type

Error message

Cannot drop user type '%s.%s' as it is still used by tables %s

What it means

The user-defined type is still referenced by one or more table columns, so Cassandra refuses to drop it. Tables may reference the type directly or through nested UDTs, and dropping it would corrupt those table schemas.

Solutions

  1. Identify the listed tables and migrate/drop or ALTER them to stop using the type, then reissue DROP TYPE
  2. Search system_schema.columns and UDT fields for the type before cleanup
  3. If the data must be preserved, create a replacement table with the new schema and copy data over

Example fix

// before
DROP TYPE ks.geo;
// after
ALTER TABLE ks.sites DROP location;  -- stop using the type
DROP TYPE ks.geo;
Defensive patterns

Strategy: validation

Validate before calling

var cols = session.execute("SELECT table_name, column_name FROM system_schema.columns WHERE keyspace_name=?", ks);
// match type columns against the UDT name, including nested UDT field types

Try / catch

try { session.execute("DROP TYPE " + ks + "." + type); } catch (InvalidRequest e) { if (e.getMessage().contains("still used by tables")) migrateTablesFirst(); else throw e; }

Prevention

When it happens

Trigger: DROP TYPE on a UDT while keyspace.tables.referencingUserType(name) is non-empty — any table with a column (including clustering/key columns or nested UDT fields) of that type.

Common situations: Dropping legacy UDTs while old tables still use them; migrations that migrate data off a type but forget a table; blind cleanup scripts.

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

Appendix: source

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

                      keyspaceName,
                      typeName,
                      join(", ", transform(functions, f -> f.name().toString())));
        }

        Iterable<UserType> types = keyspace.types.referencingUserType(name);
        if (!isEmpty(types))
        {
            throw ire("Cannot drop user type '%s.%s' as it is still used by user types %s",
                      keyspaceName,
                      typeName,
                      join(", ", transform(types, UserType::getNameAsString)));

        }

        Iterable<TableMetadata> tables = keyspace.tables.referencingUserType(name);
        if (!isEmpty(tables))
        {
            throw ire("Cannot drop user type '%s.%s' as it is still used by tables %s",
                      keyspaceName,
                      typeName,
                      join(", ", transform(tables, t -> t.name)));
        }

        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.types.without(type)));
    }

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

    public void authorize(ClientState client)
    {
        client.ensureAllTablesPermission(keyspaceName, Permission.DROP);
    }

View on GitHub (pinned to 88fd0f6a0e)