{"record":{"id":"74a6bb79f39a72c4","repo":"apache/cassandra","slug":"target-keyspace-s-has-same-udt-name-s-as-sou","errorCode":null,"errorMessage":"Target keyspace '%s' has same UDT name '%s' as source keyspace '%s' but with different structure.","messagePattern":"Target keyspace '(.+?)' has same UDT name '(.+?)' as source keyspace '(.+?)' but with different structure\\.","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java","lineNumber":164,"sourceCode":"        {\n            if (ifNotExists)\n                return schema;\n\n            throw new AlreadyExistsException(targetKeyspace, targetTableName);\n        }\n\n        if (!sourceKeyspace.equalsIgnoreCase(targetKeyspace))\n        {\n            Set<String> missingUserTypes = Sets.newHashSet();\n            // for different keyspace, if source table used some udts and the target table also need them\n            for (ByteBuffer sourceUserTypeName : sourceTableMeta.getReferencedUserTypes())\n            {\n                Optional<UserType> targetUserType = targetKeyspaceMeta.types.get(sourceUserTypeName);\n                Optional<UserType> sourceUserType = sourceKeyspaceMeta.types.get(sourceUserTypeName);\n                if (targetUserType.isPresent() && sourceUserType.isPresent())\n                {\n                    if (!sourceUserType.get().equalsWithOutKs(targetUserType.get()))\n                        throw ire(\"Target keyspace '%s' has same UDT name '%s' as source keyspace '%s' but with different structure.\",\n                                  targetKeyspace,\n                                  UTF8Type.instance.getString(targetUserType.get().name),\n                                  sourceKeyspace);\n                }\n                else\n                {\n                    missingUserTypes.add(UTF8Type.instance.compose(sourceUserTypeName));\n                }\n            }\n\n            if (!missingUserTypes.isEmpty())\n                throw ire(\"UDTs %s do not exist in target keyspace '%s'.\",\n                          missingUserTypes.stream().sorted().collect(Collectors.joining(\", \")),\n                          targetKeyspace);\n        }\n\n        // Guardrail on columns per table\n        Guardrails.columnsPerTable.guard(sourceTableMeta.columns().size(), targetTableName, false, state);","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CopyTableStatement.java#L146-L182","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Alter the target keyspace's UDT so it structurally matches the source UDT (ALTER TYPE or drop/recreate it identically)","Drop the conflicting target UDT (if unused) so the copy can recreate a matching one","Copy into a different target keyspace that has no conflicting UDT name"],"exampleFix":"// before\ncREATE TABLE src.t WITH ... ; CREATE TABLE tgt.t ...  -- tgt has UDT 'addr' with different fields\n// after\nALTER TYPE tgt.addr ADD zip int;  -- make tgt.addr match src.addr before copying","handlingStrategy":"validation","validationCode":"for (UserType udt : sourceKs.types) {\n    Optional<UserType> tgt = targetKs.types.get(udt.getNameAsString());\n    if (tgt.isPresent() && !udt.equalsWithOutKs(tgt.get()))\n        throw new IllegalStateException(\"UDT \" + udt.getNameAsString() + \" differs between keyspaces\");\n}","typeGuard":"boolean isCompatible(UserType src, Optional<UserType> tgt) { return tgt.isPresent() && src.equalsWithOutKs(tgt.get()); }","tryCatchPattern":"try { copyTable(sourceKs, sourceTable, targetKs, targetTable); }\ncatch (InvalidRequestException e) { if (e.getMessage().contains(\"same UDT name\")) reconcileUdts(targetKs); else throw e; }","preventionTips":["Keep UDT definitions in sync across keyspaces (single source of truth for schema migrations)","Diff UDT definitions between source and target keyspaces before copying tables","Avoid independently evolving duplicate UDTs; share one keyspace for common types"],"tags":["cql","udt","schema","keyspace-conflict","schema-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}