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 filters ('{filter1}' and '{filter2}').

What it means

Two indexes share the same database name and table but have different filter expressions (e.g. WHERE clauses on partial/filtered indexes). A single database index can only carry one filter.

Solutions

  1. Use identical HasFilter expressions on both indexes.
  2. Give the indexes distinct database names via HasDatabaseName so each can have its own filter.
  3. Remove one of the indexes if it is redundant.
  4. If no filter is intended, ensure neither index sets HasFilter.

Example fix

// before
modelBuilder.Entity<User>().HasIndex(u => u.Email)
    .HasFilter("[Email] IS NOT NULL").HasDatabaseName("IX_User_Email");
modelBuilder.Entity<DeletedUser>().ToTable("User").HasIndex(u => u.Email)
    .HasFilter("[Email] IS NULL").HasDatabaseName("IX_User_Email");

// after: distinct names so each filter is independent
modelBuilder.Entity<DeletedUser>().ToTable("User").HasIndex(u => u.Email)
    .HasFilter("[Email] IS NULL").HasDatabaseName("IX_User_Email_Deleted");
Defensive patterns

Strategy: validation

Validate before calling

// Detect filter mismatches for colliding index names.
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 filters = g.Select(i => i.GetFilter() ?? string.Empty).Distinct();
    if (filters.Count() > 1)
        Console.WriteLine($"Index '{g.Key.Name}' has conflicting filters: {string.Join(" | ", filters)}.");
}

Prevention

When it happens

Trigger: RelationalIndexExtensions.AreCompatible with shouldThrow:true when index.GetFilter(storeObject) != duplicateIndex.GetFilter(storeObject). Happens when HasIndex(...).HasFilter(...) is used inconsistently on two indexes that resolve to the same database name.

Common situations: Filtered indexes on SQL Server/PostgreSQL with colliding names; table-splitting where one entity wants a partial index and another does not; legacy migrations with manually edited filter strings.

Related errors


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

Appendix: source

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

                        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(),
                            duplicateIndex.DeclaringEntityType.DisplayName(),
                            index.DeclaringEntityType.GetSchemaQualifiedTableName(),
                            index.GetDatabaseName(storeObject)))
                    : false
                : index.GetFilter(storeObject) == duplicateIndex.GetFilter(storeObject)
                || (shouldThrow
                    ? throw new InvalidOperationException(
                        RelationalStrings.DuplicateIndexFiltersMismatch(
                            index.DisplayName(),
                            index.DeclaringEntityType.DisplayName(),
                            duplicateIndex.DisplayName(),
                            duplicateIndex.DeclaringEntityType.DisplayName(),
                            index.DeclaringEntityType.GetSchemaQualifiedTableName(),
                            index.GetDatabaseName(storeObject),
                            index.GetFilter(),
                            duplicateIndex.GetFilter()))
                    : false);
    }

    private static string FormatColumnNames(IEnumerable<string> columnNames)
        => "{" + string.Join(", ", columnNames.Select(n => "'" + n + "'")) + "}";

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in

View on GitHub (pinned to 3a2006ef56)