{"record":{"id":"014f6a869200044f","repo":"vitessio/vitess","slug":"vt12002-014f6a","errorCode":"VT12002","errorMessage":"VT12002: unsupported: cross-shard foreign keys between table '%s' and '%s'","messagePattern":"VT12002: unsupported: cross-shard foreign keys between table '(.+?)' and '(.+?)'","errorType":"error_code","errorClass":"VitessError","httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/insert.go","lineNumber":165,"sourceCode":"\treturn &Sequential{Sources: []Operator{delOp, insOp}}\n}\n\nfunc checkAndCreateInsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTbl *vindexes.BaseTable, routing Routing) Operator {\n\tinsOp := createInsertOperator(ctx, ins, vTbl, routing)\n\n\t// Find the foreign key mode and for unmanaged foreign-key-mode, we don't need to do anything.\n\tksMode, err := ctx.VSchema.ForeignKeyMode(vTbl.Keyspace.Name)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif ksMode != vschemapb.Keyspace_managed {\n\t\treturn insOp\n\t}\n\n\tparentFKs := ctx.SemTable.GetParentForeignKeysList()\n\tchildFks := ctx.SemTable.GetChildForeignKeysList()\n\tif len(parentFKs) > 0 {\n\t\tpanic(vterrors.VT12002(vTbl.String(), parentFKs[0].Table.String()))\n\t}\n\tif len(childFks) > 0 {\n\t\tif ins.Action == sqlparser.ReplaceAct {\n\t\t\tpanic(vterrors.VT12001(\"REPLACE INTO with foreign keys\"))\n\t\t}\n\t\tif len(ins.OnDup) > 0 {\n\t\t\trows := getRowsOrError(ins)\n\t\t\treturn createUpsertOperator(ctx, ins, insOp, rows, vTbl)\n\t\t}\n\t}\n\treturn insOp\n}\n\nfunc getRowsOrError(ins *sqlparser.Insert) sqlparser.Values {\n\tif rows, ok := ins.Rows.(sqlparser.Values); ok {\n\t\treturn rows\n\t}\n\tpanic(vterrors.VT12001(\"ON DUPLICATE KEY UPDATE with foreign keys with select statement\"))","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/insert.go#L147-L183","documentation":"VT12002: the insert plan detected foreign keys spanning shards. When the SemTable reports parent (or child) foreign keys for the target table, the planner cannot produce a correct multi-shard insert plan, because parent and child rows may live on different shards. It panics with the target table and the first conflicting parent table in the message.","triggerScenarios":"An INSERT (or REPLACE) into a table that has foreign-key relationships (GetParentForeignKeysList non-empty, or child FKs in later checks) where related tables are in different shards/keyspaces, during checkAndCreateInsertOperator.","commonSituations":"Enabling managed foreign keys in a sharded Vitess keyspace without co-locating parent/child tables via Vindexes; application schemas with FKs migrated as-is into sharded deployments.","solutions":["Co-locate parent and child tables on the same shard using appropriate vindexes (same sharding key) so FK relationships stay intra-shard","Remove database-level foreign keys from sharded tables and enforce referential integrity in the application","Keep FK-related tables unsharded (single-shard keyspace) if write patterns allow","Check `Show`/vschema configuration to confirm which FKs the SemTable sees and adjust the schema"],"exampleFix":"-- before: parent in another keyspace/shard with FK enforced\nCREATE TABLE child (id INT, pid INT, FOREIGN KEY (pid) REFERENCES parent(id));\n-- after: enforce in application, no FK in sharded schema\nCREATE TABLE child (id INT, pid INT);\n-- validate pid exists in app code before insert","handlingStrategy":"validation","validationCode":"// Before deploying, verify FK tables share the same sharding key/vindex\n// or drop FKs from sharded tables entirely:\nSELECT TABLE_NAME, REFERENCED_TABLE_NAME FROM information_schema.KEY_COLUMN_USAGE\n WHERE REFERENCED_TABLE_NAME IS NOT NULL;","typeGuard":null,"tryCatchPattern":"_, err := db.ExecContext(ctx, insertSQL)\nif err != nil && strings.Contains(err.Error(), \"VT12002\") {\n  // foreign key spans shards: remove FK or co-locate tables\n}","preventionTips":["Use same-sharding-key vindexes so parent/child rows are co-located","Enforce referential integrity in application code on sharded tables","Keep FK relationships inside single-shard keyspaces","Review vschema and FK configuration after every schema change"],"tags":["go","foreign-keys","insert","sharding","unsupported"],"backgroundTag":"cross-shard-foreign-key","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}