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 sort orders.

What it means

Two indexes share the same database name and table but define different descending/ascending sort orders (IsDescending). The database cannot represent conflicting collation orders for one index.

Solutions

  1. Align the IsDescending configuration on both indexes.
  2. Give the indexes distinct database names via HasDatabaseName.
  3. Remove one of the conflicting index definitions.
  4. If only one sort order is meaningful, delete the other index.

Example fix

// before
modelBuilder.Entity<Log>().HasIndex(l => l.Ts).IsDescending().HasDatabaseName("IX_Log_Ts");
modelBuilder.Entity<LogArchive>().ToTable("Log").HasIndex(l => l.Ts).HasDatabaseName("IX_Log_Ts");

// after: align sort order
modelBuilder.Entity<LogArchive>().ToTable("Log").HasIndex(l => l.Ts).IsDescending().HasDatabaseName("IX_Log_Ts");
Defensive patterns

Strategy: validation

Validate before calling

// Detect sort-order 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 orders = g.Select(i => i.IsDescending == null ? "null" : string.Join(",", i.IsDescending)).Distinct();
    if (orders.Count() > 1)
        Console.WriteLine($"Index '{g.Key.Name}' has conflicting sort orders.");
}

Prevention

When it happens

Trigger: RelationalIndexExtensions.AreCompatible with shouldThrow:true when (index.IsDescending is null) != (duplicateIndex.IsDescending is null), or both non-null but not SequenceEqual. Triggered by HasIndex(...).IsDescending(...) values that mismatch across two indexes sharing a database name.

Common situations: EF7+ descending-index support used inconsistently on colliding indexes; one index left at default (null IsDescending) and another explicitly setting descending; copy/paste of HasDatabaseName across index definitions with different sort orders.

Related errors


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

Appendix: source

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

        }

        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(),
                            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),

View on GitHub (pinned to 3a2006ef56)