dotnet/efcore · error · InvalidOperationException
The foreign keys on ' ' and on ' ' are both mapped to ' …
Error message
The foreign keys {foreignKeyProperties1} on '{entityType1}' and {foreignKeyProperties2} on '{entityType2}' are both mapped to '{table}.{foreignKeyName}', but referencing different principal tables ('{principalTable1}' and '{principalTable2}'). What it means
Two foreign keys are mapped to the same constraint on the same table but reference different principal tables, which is impossible for a single FK constraint. AreCompatible throws DuplicateForeignKeyPrincipalTableMismatch when the principal StoreObjectIdentifiers differ or cannot be resolved.
Solutions
- Remove the shared HasConstraintName override so each FK gets a distinct default name based on its principal.
- If overrides are intentional, ensure each name is unique per principal-table combination.
- Verify the principal entity of each relationship is the one you expect (check HasOne/WithMany targets).
Example fix
// before
modelBuilder.Entity<Loan>()
.HasOne(l => l.Account).WithMany().HasForeignKey(l => l.AccountId)
.HasConstraintName("FK_Account");
modelBuilder.Entity<Loan>()
.HasOne(l => l.Branch).WithMany().HasForeignKey(l => l.BranchId)
.HasConstraintName("FK_Account");
// after
modelBuilder.Entity<Loan>()
.HasOne(l => l.Branch).WithMany().HasForeignKey(l => l.BranchId)
.HasConstraintName("FK_Loan_Branch"); Defensive patterns
Strategy: validation
Validate before calling
// Ensure FKs sharing a name on the same table point to the same principal table
var conflicts = modelBuilder.Model.GetEntityTypes()
.SelectMany(e => e.GetDeclaredForeignKeys())
.GroupBy(fk => (fk.GetConstraintName(), fk.DeclaringEntityType.GetSchemaQualifiedTableName()))
.Where(g => g.Select(fk => fk.PrincipalEntityType.GetSchemaQualifiedTableName()).Distinct().Count() > 1);
if (conflicts.Any()) throw new InvalidOperationException("FKs sharing a constraint name reference different principal tables."); Prevention
- When two relationships share a constraint name, confirm they target the same principal entity/table.
- Prefer removing HasConstraintName overrides so EF computes distinct names from principal + properties.
When it happens
Trigger: Two FKs on the same table both manually named the same via HasConstraintName but pointing at different principal entities/tables; refactor that changed which entity an FK targets without renaming the constraint.
Common situations: Two relationships on one entity (e.g. OwnerId and CustomerId) where the developer forced the same FK constraint name; TPH inheritance where base and derived declare FKs that collide.
Related errors
- The foreign keys on ' ' and on ' ' are both mapped to ' '…
- The entity type ' ' was configured to use some stored…
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- Both entity type ' ' and ' ' were configured to use ' '…
- Current value parameter
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/afce015eb3424b79.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs:67
duplicateForeignKey.DeclaringEntityType.DisplayName(),
principalTable.HasValue
? foreignKey.GetConstraintName(storeObject, principalTable.Value)
: foreignKey.GetDefaultName(),
foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
duplicateForeignKey.DeclaringEntityType.GetSchemaQualifiedTableName()))
: false;
}
if (principalTable is null
|| duplicatePrincipalTable is null
|| principalTable != duplicatePrincipalTable
|| foreignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value)
is not { } principalColumns
|| duplicateForeignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value)
is not { } duplicatePrincipalColumns)
{
return shouldThrow
? throw new InvalidOperationException(
RelationalStrings.DuplicateForeignKeyPrincipalTableMismatch(
foreignKey.Properties.Format(),
foreignKey.DeclaringEntityType.DisplayName(),
duplicateForeignKey.Properties.Format(),
duplicateForeignKey.DeclaringEntityType.DisplayName(),
foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
principalTable.HasValue
? foreignKey.GetConstraintName(storeObject, principalTable.Value)
: foreignKey.GetDefaultName(),
principalType.GetSchemaQualifiedTableName(),
duplicatePrincipalType.GetSchemaQualifiedTableName()))
: false;
}
if (!columnNames.SequenceEqual(duplicateColumnNames))
{
return shouldThrow
? throw new InvalidOperationException(View on GitHub (pinned to 3a2006ef56)