apache/cassandra · error · InvalidRequestException

Cannot drop user type

Error message

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

What it means

The user-defined type is still referenced by one or more user functions, so Cassandra refuses to drop it. Dropping a UDT that functions depend on would leave the function signatures broken, so the dependency check blocks the drop and names the offending functions.

Solutions

  1. Drop or ALTER the listed functions so they no longer reference the type, then reissue DROP TYPE
  2. Use system_schema.functions to find functions referencing the type
  3. If the type definition only needs to change, ALTER TYPE instead of drop/recreate

Example fix

// before
DROP TYPE ks.geo;
// after
DROP FUNCTION ks.dist(geo);
DROP TYPE ks.geo;
Defensive patterns

Strategy: validation

Validate before calling

var funcs = session.execute("SELECT function_name FROM system_schema.functions WHERE keyspace_name=?", ks);
// also inspect argument_types and return_type for the UDT name before dropping

Try / catch

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

Prevention

When it happens

Trigger: DROP TYPE on a UDT while keyspace.userFunctions.referencingUserType(name) is non-empty — i.e. functions whose signatures (params/return type) use the type.

Common situations: Schemas where UDFs were created using UDTs and later attempts to clean up the types; refactoring types without auditing function dependencies.

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

Appendix: source

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

            if (ifExists)
                return schema;

            throw ire("Type '%s.%s' doesn't exist", keyspaceName, typeName);
        }

        /*
         * We don't want to drop a type unless it's not used anymore (mainly because
         * if someone drops a type and recreates one with the same name but different
         * 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))
        {

View on GitHub (pinned to 88fd0f6a0e)