dotnet/efcore · error · InvalidOperationException

The indexes on ' ' and on ' ' are both mapped to ' . ', but…

Error message

The indexes {index1} on '{entityType1}' and {index2} on '{entityType2}' are both mapped to '{table}.{indexName}', but with different columns ({columnNames1} and {columnNames2}).

What it means

Two indexes share the same database name and table but cover different columns. The database cannot have two indexes with the same name on different column sets.

Solutions

  1. Give each index a distinct HasDatabaseName.
  2. Make the two indexes reference the same properties/columns if they are meant to be one index.
  3. Drop the redundant index.
  4. Re-check that an index on an owned type is not silently duplicating the owner's index.

Example fix

// before
modelBuilder.Entity<Order>().HasIndex(o => o.CustomerId).HasDatabaseName("IX_Order_Customer");
modelBuilder.Entity<OrderDetail>().ToTable("Order").HasIndex(d => d.ProductId).HasDatabaseName("IX_Order_Customer");

// after
modelBuilder.Entity<Order>().HasIndex(o => o.CustomerId).HasDatabaseName("IX_Order_Customer");
modelBuilder.Entity<OrderDetail>().ToTable("Order").HasIndex(d => d.ProductId).HasDatabaseName("IX_Order_Product");
Defensive patterns

Strategy: validation

Validate before calling

// Detect index-name collisions with differing columns on the same table.
var groups = modelBuilder.Model.GetEntityTypes()
    .SelectMany(e => e.GetDeclaredIndexes())
    .GroupBy(i => new { Name = i.GetDatabaseName(), Table = i.DeclaringEntityType.GetSchemaQualifiedTableName() })
    .Where(g => g.Count() > 1);
foreach (var g in groups)
{
    var cols = g.Select(i => string.Join(",", i.Properties.Select(p => p.GetColumnName()))).Distinct();
    if (cols.Count() > 1)
        Console.WriteLine($"Index '{g.Key.Name}' on '{g.Key.Table}' has conflicting column sets.");
}

Prevention

When it happens

Trigger: RelationalIndexExtensions.AreCompatible with shouldThrow:true when !columnNames.SequenceEqual(duplicateColumnNames). Triggered when HasDatabaseName gives the same name to indexes on different property sets mapped to the same table.

Common situations: Table-splitting where multiple entities define indexes on the shared table with a colliding name; explicit HasDatabaseName copy/paste errors; an owned entity's index colliding with the owner's index.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/7239ecd95dbea846. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs:70

            || duplicateColumnNames == null)
        {
            return shouldThrow
                ? throw new InvalidOperationException(
                    RelationalStrings.DuplicateIndexTableMismatch(
                        index.DisplayName(),
                        index.DeclaringEntityType.DisplayName(),
                        duplicateIndex.DisplayName(),
                        duplicateIndex.DeclaringEntityType.DisplayName(),
                        index.GetDatabaseName(storeObject),
                        index.DeclaringEntityType.GetSchemaQualifiedTableName(),
                        duplicateIndex.DeclaringEntityType.GetSchemaQualifiedTableName()))
                : false;
        }

        if (!columnNames.SequenceEqual(duplicateColumnNames))
        {
            return shouldThrow
                ? throw new InvalidOperationException(
                    RelationalStrings.DuplicateIndexColumnMismatch(
                        index.DisplayName(),
                        index.DeclaringEntityType.DisplayName(),
                        duplicateIndex.DisplayName(),
                        duplicateIndex.DeclaringEntityType.DisplayName(),
                        index.DeclaringEntityType.GetSchemaQualifiedTableName(),
                        index.GetDatabaseName(storeObject),
                        FormatColumnNames(columnNames),
                        FormatColumnNames(duplicateColumnNames)))
                : false;
        }

        return index.IsUnique != duplicateIndex.IsUnique
            ? shouldThrow
                ? throw new InvalidOperationException(
                    RelationalStrings.DuplicateIndexUniquenessMismatch(
                        index.DisplayName(),
                        index.DeclaringEntityType.DisplayName(),

View on GitHub (pinned to 3a2006ef56)