dotnet/efcore · error · InvalidOperationException

The indexes {index1} on '{entityType1}' and {index2} on '{en

Error message

The indexes {index1} on '{entityType1}' and {index2} on '{entityType2}' are both mapped to '{table}.{indexName}', but with different uniqueness configurations.

What it means

Thrown by RelationalIndexExtensions.AreCompatible when two same-named indexes on the same table have matching columns but disagree on IsUnique. A physical database index is either unique or not, so EF rejects two conflicting uniqueness configurations under one name.

Source

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

        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(),
                        duplicateIndex.DisplayName(),
                        duplicateIndex.DeclaringEntityType.DisplayName(),
                        index.DeclaringEntityType.GetSchemaQualifiedTableName(),
                        index.GetDatabaseName(storeObject)))
                : false
            : (index.IsDescending is null) != (duplicateIndex.IsDescending is null)
            || (index.IsDescending is not null
                && duplicateIndex.IsDescending is not null
                && !index.IsDescending.SequenceEqual(duplicateIndex.IsDescending))
                ? shouldThrow
                    ? throw new InvalidOperationException(
                        RelationalStrings.DuplicateIndexSortOrdersMismatch(
                            index.DisplayName(),
                            index.DeclaringEntityType.DisplayName(),
                            duplicateIndex.DisplayName(),

View on GitHub (pinned to dbf9771522)

Solutions

  1. Apply IsUnique() (or omit it) consistently on every index that shares the database name.
  2. If the uniqueness genuinely differs, the indexes are different — give them distinct HasDatabaseName values.
  3. Consolidate the index declaration onto the principal entity type of the shared table.

Example fix

// before
modelBuilder.Entity<User>().HasIndex(u => u.Email).IsUnique().HasDatabaseName("IX_Email");
modelBuilder.Entity<UserProfile>().HasIndex(u => u.Email).HasDatabaseName("IX_Email"); // non-unique -> throws

// after
modelBuilder.Entity<UserProfile>().HasIndex(u => u.Email).IsUnique().HasDatabaseName("IX_Email");
Defensive patterns

Strategy: validation

Validate before calling

// Assert uniqueness agreement for same-named indexes on a shared table
var group = from et in model.GetEntityTypes()
            from idx in et.GetDeclaredIndexes()
            where idx.GetDatabaseName() is string n
            group idx by idx.GetDatabaseName() into g
            where g.DistinctBy(i => i.IsUnique).Count() > 1
            select g.Name;
if (group.Any()) throw new InvalidOperationException("Uniqueness mismatch on index: " + string.Join(", ", group));

Prevention

When it happens

Trigger: Lines 83-93: index.IsUnique != duplicateIndex.IsUnique after columns already matched. Typically from calling IsUnique() on one HasIndex but not the matching one across two table-sharing entity types.

Common situations: Table splitting where one entity declares a unique index and the co-mapped entity declares the same index non-unique; a derived type overriding uniqueness without changing the index name; copy-pasting index configs and forgetting the IsUnique call.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/344f9171d67d97bc. Report an issue: GitHub.