apache/cassandra · error · InvalidRequestException

Cannot drop user type

Error message

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

What it means

Reference guard in DropTypeStatement.apply(): the user type being dropped is still nested inside other user types in the same keyspace (detected via keyspace.types referencingUserType). Dropping it would corrupt the dependent type definitions, so the statement is rejected with InvalidRequestException listing the dependent types (this is check 2 of the three reference checks the code documents).

Solutions

  1. Drop or alter the dependent user types first so they no longer reference the type; then retry the DROP TYPE; alternatively keep the type if the nested usage is still required.

Example fix

// before
DROP TYPE ks.address;
// after
DROP TYPE ks.user;      -- depends on address
DROP TYPE ks.address;
Defensive patterns

Strategy: validation

Validate before calling

var types = session.execute("SELECT type_name, field_types FROM system_schema.types WHERE keyspace_name=?", ks);
// scan field_types of each UDT for the type being dropped

Try / catch

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

Prevention

When it happens

Trigger: DROP TYPE on a UDT while keyspace.types.referencingUserType(name) is non-empty — other UDTs containing the type as a field (directly or nested).

Common situations: Cleaning up old UDTs in schemas with nested types (e.g. address nested in user); dropping inner types of a type hierarchy without dropping dependents first.

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

Appendix: source

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

         * definition with the previous name still in use, things can get messy).
         * We have three places to check:
         * 1) UDFs and UDAs using the type
         * 2) other user type that can nest the one we drop and
         * 3) existing tables referencing the type (maybe in a nested way).
         */
        Iterable<UserFunction> functions = keyspace.userFunctions.referencingUserType(name);
        if (!isEmpty(functions))
        {
            throw ire("Cannot drop user type '%s.%s' as it is still used by functions %s",
                      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)));
    }

View on GitHub (pinned to 88fd0f6a0e)