apache/cassandra · error · InvalidRequestException
UDTs do not exist in target keyspace ' '.
Error message
UDTs %s do not exist in target keyspace '%s'.
What it means
CopyTableStatement.apply validation: the source table references user-defined types that are absent from the target keyspace, so the table cannot be copied until those UDTs exist there. Thrown as InvalidRequestException during schema transformation.
Solutions
- Create the listed UDT(s) in the target keyspace with identical structure before re-running the copy
- Copy the full schema (keyspace with types) rather than just the table
- Run statements in dependency order: CREATE TYPE before CREATE TABLE
Example fix
// before CREATE TABLE tgt.t ... -- fails: UDT addr missing in tgt // after CREATE TYPE tgt.addr (street text, zip int); CREATE TABLE tgt.t ...
Defensive patterns
Strategy: validation
Validate before calling
List<String> missing = sourceTable.columns.stream()
.flatMap(c -> referencedUdts(c.type).stream())
.filter(n -> !targetKs.types.get(UTF8Type.instance.decompose(n)).isPresent())
.collect(Collectors.toList());
if (!missing.isEmpty()) throw new IllegalStateException("Missing UDTs in target: " + missing); Try / catch
try { copyTable(...); }
catch (InvalidRequestException e) { if (e.getMessage().startsWith("UDTs ")) createMissingUdts(parseNames(e.getMessage()), targetKs); else throw e; } Prevention
- Always create all UDTs in the target keyspace before copying tables
- Migrate schemas as complete units (types + tables), never tables alone
- Maintain an ordered migration script: keyspaces, types, functions, then tables
When it happens
Trigger: CopyTableStatement.apply with one or more source UDT names having no counterpart (Optional.empty) in targetKeyspaceMeta.types; the message lists the missing names sorted.
Common situations: Copying a table into a fresh keyspace without first creating its UDTs; running schema-restore scripts out of order (table before types).
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Cannot add new field
- Cannot add new field
- Cannot drop non-frozen column
- Invalid field deletion operation for non-UDT column
- Non-frozen UDTs are not allowed inside collections:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ae8c09ac4d8c4f9c.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:176
{
Optional<UserType> targetUserType = targetKeyspaceMeta.types.get(sourceUserTypeName);
Optional<UserType> sourceUserType = sourceKeyspaceMeta.types.get(sourceUserTypeName);
if (targetUserType.isPresent() && sourceUserType.isPresent())
{
if (!sourceUserType.get().equalsWithOutKs(targetUserType.get()))
throw ire("Target keyspace '%s' has same UDT name '%s' as source keyspace '%s' but with different structure.",
targetKeyspace,
UTF8Type.instance.getString(targetUserType.get().name),
sourceKeyspace);
}
else
{
missingUserTypes.add(UTF8Type.instance.compose(sourceUserTypeName));
}
}
if (!missingUserTypes.isEmpty())
throw ire("UDTs %s do not exist in target keyspace '%s'.",
missingUserTypes.stream().sorted().collect(Collectors.joining(", ")),
targetKeyspace);
}
// Guardrail on columns per table
Guardrails.columnsPerTable.guard(sourceTableMeta.columns().size(), targetTableName, false, state);
sourceTableMeta.columns().forEach(columnMetadata -> {
if (columnMetadata.type.isVector())
{
Guardrails.vectorTypeEnabled.ensureEnabled(columnMetadata.name.toString(), state);
int dimensions = ((VectorType) columnMetadata.type).dimension;
Guardrails.vectorDimensions.guard(dimensions, columnMetadata.name.toString(), false, state);
}
});
// Guardrail to check whether creation of new COMPACT STORAGE tables is allowed
if (sourceTableMeta.isCompactTable())View on GitHub (pinned to 88fd0f6a0e)