apache/cassandra · error · InvalidRequestException

Target keyspace ' ' has same UDT name ' ' as source…

Error message

Target keyspace '%s' has same UDT name '%s' as source keyspace '%s' but with different structure.

What it means

Thrown during COPY TABLE (snapshot-style clone of a table schema into another keyspace) when the target keyspace already declares a user-defined type with the same name as one used by the source table, but its field list/types differ. Cassandra refuses to guess which UDT definition is intended, since cloning columns referencing the source UDT would silently bind to an incompatible type.

Solutions

  1. Alter the target keyspace's UDT so it structurally matches the source UDT (ALTER TYPE or drop/recreate it identically)
  2. Drop the conflicting target UDT (if unused) so the copy can recreate a matching one
  3. Copy into a different target keyspace that has no conflicting UDT name

Example fix

// before
cREATE TABLE src.t WITH ... ; CREATE TABLE tgt.t ...  -- tgt has UDT 'addr' with different fields
// after
ALTER TYPE tgt.addr ADD zip int;  -- make tgt.addr match src.addr before copying
Defensive patterns

Strategy: validation

Validate before calling

for (UserType udt : sourceKs.types) {
    Optional<UserType> tgt = targetKs.types.get(udt.getNameAsString());
    if (tgt.isPresent() && !udt.equalsWithOutKs(tgt.get()))
        throw new IllegalStateException("UDT " + udt.getNameAsString() + " differs between keyspaces");
}

Type guard

boolean isCompatible(UserType src, Optional<UserType> tgt) { return tgt.isPresent() && src.equalsWithOutKs(tgt.get()); }

Try / catch

try { copyTable(sourceKs, sourceTable, targetKs, targetTable); }
catch (InvalidRequestException e) { if (e.getMessage().contains("same UDT name")) reconcileUdts(targetKs); else throw e; }

Prevention

When it happens

Trigger: Running CREATE TABLE ... WITH ... or the CopyTableStatement against a target keyspace that has a same-named UDT whose fields are not structurally equal (equalsWithOutKs) to the source keyspace's UDT.

Common situations: Cloning a table between keyspaces after one keyspace's UDT was independently evolved (fields added/renamed); restoring a schema dump where UDTs drifted between environments.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java:164

        {
            if (ifNotExists)
                return schema;

            throw new AlreadyExistsException(targetKeyspace, targetTableName);
        }

        if (!sourceKeyspace.equalsIgnoreCase(targetKeyspace))
        {
            Set<String> missingUserTypes = Sets.newHashSet();
            // for different keyspace, if source table used some udts and the target table also need them
            for (ByteBuffer sourceUserTypeName : sourceTableMeta.getReferencedUserTypes())
            {
                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);

View on GitHub (pinned to 88fd0f6a0e)