dotnet/efcore · error · InvalidOperationException

The index {indexProperties} on the entity type '{entityType}

Error message

The index {indexProperties} on the entity type '{entityType}' cannot contain the complex property '{property}' because it's mapped to multiple columns. Reference each scalar property of the complex type individually instead.

What it means

Thrown by ValidateIndexOnComplexProperty (RelationalModelValidator.cs:2775-2783) when an index directly references a complex property (not a scalar leaf inside it) that is not mapped to JSON. A non-JSON complex property expands to multiple columns, so it cannot be part of an index as a single entity — you must reference each scalar property individually.

Source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:2778

        if (inJsonComplex)
        {
            return;
        }

        base.ValidateIndexProperty(index, property, logger);
    }

    /// <inheritdoc />
    protected override void ValidateIndexOnComplexProperty(
        IIndex index,
        IReadOnlyList<IComplexProperty> complexProperties,
        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
    {
        var nonJsonComplexProperty = complexProperties.FirstOrDefault(cp => !cp.ComplexType.IsMappedToJson());
        if (nonJsonComplexProperty != null)
        {
            throw new InvalidOperationException(
                RelationalStrings.IndexOnNonJsonComplexProperty(
                    index.Properties.Format(),
                    index.DeclaringEntityType.DisplayName(),
                    nonJsonComplexProperty.Name));
        }

        if (index.IsUnique)
        {
            // Currently not supported. We have special logic for unique indexes in the update pipeline
            // and query that would need to be updated to support this.
            throw new InvalidOperationException(
                RelationalStrings.UniqueIndexOnComplexProperty(
                    index.Properties.Format(),
                    index.DeclaringEntityType.DisplayName(),
                    complexProperties[0].Name));
        }
    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Replace the complex property in the index with its individual scalar properties (e.g., HasIndex(e => e.Address.City, e => e.Address.ZipCode)).
  2. If you want the whole complex value indexed as JSON, map the complex property with ToJson and then index a leaf inside it.

Example fix

// before: indexing the complex property itself
modelBuilder.Entity<Customer>()
    .ComplexProperty(c => c.Address);
modelBuilder.Entity<Customer>().HasIndex(c => c.Address); // throws

// after: index individual scalar properties
modelBuilder.Entity<Customer>().HasIndex(c => new { c.Address.City, c.Address.ZipCode });
Defensive patterns

Strategy: validation

Validate before calling

// Detect indexes that reference a non-JSON complex property directly.
foreach (var index in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetDeclaredIndexes()))
{
    foreach (var prop in index.Properties)
    {
        if (prop is IComplexProperty cp && !cp.ComplexType.IsMappedToJson())
            Console.WriteLine($"Index on {index.DeclaringEntityType.DisplayName()} references complex property '{cp.Name}' — index scalar leaves instead.");
    }
}

Prevention

When it happens

Trigger: Calling HasIndex with a lambda that selects a complex property itself (not a scalar inside it), where the complex property is configured with the default table-per-column mapping (not ToJson). The validator finds the first complex property in the path whose ComplexType.IsMappedToJson() is false.

Common situations: Indexing e => e.Address (a complex property/value object) instead of e => e.Address.City. The developer expects EF to index 'the address' but EF needs a concrete scalar column.

Related errors


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