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 with different uniqueness configurations. What it means
Two foreign keys share a constraint name and table but one is configured as unique and the other as non-unique. The relational layer cannot map two structurally different constraints to one database object.
Solutions
- Make both FKs agree on uniqueness (both unique or both non-unique) by changing the relationship multiplicity on one side.
- Assign distinct constraint names with HasConstraintName so the two FKs map to separate database constraints.
- Remap one relationship to different columns so it no longer collides.
- Drop the redundant FK if both relationships are semantically the same.
Example fix
// before: owned (unique) FK collides with a separate non-unique FK on the same columns
modelBuilder.Entity<User>().OwnsOne(u => u.Profile);
modelBuilder.Entity<User>().HasMany(u => u.Profiles).WithOne().HasForeignKey(p => p.UserId);
// after: keep one relationship; remove the conflicting second FK or rename it
modelBuilder.Entity<User>().OwnsOne(u => u.Profile);
// or, if both are needed, give the second a distinct constraint name
modelBuilder.Entity<User>().HasMany(u => u.Profiles).WithOne().HasForeignKey(p => p.UserId)
.HasConstraintName("FK_Profile_User_Many"); Defensive patterns
Strategy: validation
Validate before calling
// Detect uniqueness mismatch before model validation throws.
var fks = modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys());
foreach (var fk in fks)
{
var name = fk.GetConstraintName();
foreach (var dup in fks.Where(o => o != fk && o.GetConstraintName() == name
&& o.DeclaringEntityType.GetSchemaQualifiedTableName() == fk.DeclaringEntityType.GetSchemaQualifiedTableName()))
{
if (fk.IsUnique != dup.IsUnique)
Console.WriteLine($"Uniqueness mismatch on constraint '{name}'.");
}
} Prevention
- Decide relationship multiplicity (1:1 vs 1:*) up front and apply it consistently to all FKs that may share a constraint name.
- Avoid declaring both an ownership and a regular relationship on the same FK columns.
- Validate the model in tests before runtime.
When it happens
Trigger: RelationalForeignKeyExtensions.AreCompatible with shouldThrow:true when foreignKey.IsUnique != duplicateForeignKey.IsUnique. Typical with shared ownership, TPT, or table-splitting where one path is 1:1 (unique) and another is 1:* (non-unique) but both FKs resolve to the same constraint name.
Common situations: An owned entity also participates in a regular one-to-many relationship using the same FK columns; an alternate key relationship defined alongside a primary FK; explicit HasConstraintName reuse across mismatched relationships.
Related errors
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- The foreign keys on ' ' and on ' ' are both mapped to ' …
- The indexes on ' ' and on ' ' are both mapped to ' . ', but…
- The indexes on ' ' and on ' ' are both mapped to ' ', but…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/db7df2b0c1bdf486.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs:117
{
return shouldThrow
? throw new InvalidOperationException(
RelationalStrings.DuplicateForeignKeyPrincipalColumnMismatch(
foreignKey.Properties.Format(),
foreignKey.DeclaringEntityType.DisplayName(),
duplicateForeignKey.Properties.Format(),
duplicateForeignKey.DeclaringEntityType.DisplayName(),
foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
foreignKey.GetConstraintName(storeObject, principalTable.Value),
foreignKey.PrincipalKey.Properties.FormatColumns(principalTable.Value),
duplicateForeignKey.PrincipalKey.Properties.FormatColumns(principalTable.Value)))
: false;
}
if (foreignKey.IsUnique != duplicateForeignKey.IsUnique)
{
return shouldThrow
? throw new InvalidOperationException(
RelationalStrings.DuplicateForeignKeyUniquenessMismatch(
foreignKey.Properties.Format(),
foreignKey.DeclaringEntityType.DisplayName(),
duplicateForeignKey.Properties.Format(),
duplicateForeignKey.DeclaringEntityType.DisplayName(),
foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
foreignKey.GetConstraintName(storeObject, principalTable.Value)))
: false;
}
var referentialAction = RelationalModel.ToReferentialAction(foreignKey.DeleteBehavior);
var duplicateReferentialAction = RelationalModel.ToReferentialAction(duplicateForeignKey.DeleteBehavior);
return referentialAction != duplicateReferentialAction
? shouldThrow
? throw new InvalidOperationException(
RelationalStrings.DuplicateForeignKeyDeleteBehaviorMismatch(
foreignKey.Properties.Format(),
foreignKey.DeclaringEntityType.DisplayName(),View on GitHub (pinned to 3a2006ef56)