dotnet/efcore · error · InvalidOperationException
A full-text index on '{entityType}' is defined over multiple
Error message
A full-text index on '{entityType}' is defined over multiple properties (`{properties}`). A full-text index can only target a single property. What it means
Thrown by CosmosModelValidator.ValidateFullTextIndex when an index flagged as a Cosmos full-text index spans more than one property (index.Properties.Count > 1). Azure Cosmos DB full-text indexes are single-property by design, so EF Core rejects the composite configuration at model validation time rather than sending an invalid container policy. The thrown message interpolates the entity display name and the comma-joined property names.
Source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:643
CosmosStrings.VectorIndexOnNonVector(
entityType.DisplayName(),
index.Properties[0].Name));
}
}
/// <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
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected virtual void ValidateFullTextIndex(
IIndex index,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
if (index.Properties.Count > 1)
{
throw new InvalidOperationException(
CosmosStrings.CompositeFullTextIndex(
index.DeclaringEntityType.DisplayName(),
string.Join(",", index.Properties.Select(e => e.Name))));
}
if (index.Properties[0] is not IProperty firstFullTextProperty
|| firstFullTextProperty.GetIsFullTextSearchEnabled() != true)
{
throw new InvalidOperationException(
CosmosStrings.FullTextIndexOnNonFullTextProperty(
index.DeclaringEntityType.DisplayName(),
index.Properties[0].Name,
nameof(CosmosPropertyBuilderExtensions.EnableFullTextSearch)));
}
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject toView on GitHub (pinned to dbf9771522)
Solutions
- Split the single HasFullTextIndex call into one HasFullTextIndex per property, each on its own HasIndex builder for that one property.
- Re-examine the model: if you truly need cross-property full-text search, combine the values into a single denormalized string property and full-text-index that property instead.
Example fix
// before
modelBuilder.Entity<Article>()
.HasIndex(a => new { a.Title, a.Body })
.HasFullTextIndex();
// after
modelBuilder.Entity<Article>().HasIndex(a => a.Title).HasFullTextIndex();
modelBuilder.Entity<Article>().HasIndex(a => a.Body).HasFullTextIndex(); Defensive patterns
Strategy: validation
Validate before calling
// In OnModelCreating, before HasFullTextIndex, assert single property
foreach (var index in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetIndexes()))
{
var props = index.Properties;
if (props.Count > 1 && /* is full-text: you track via a side map or metadata */) continue;
if (props.Count > 1) throw new InvalidOperationException($"Full-text index on {index.DeclaringEntityType.DisplayName()} is composite.");
} Prevention
- Centralize all HasFullTextIndex calls in one OnModelCreating region and visually verify each uses exactly one property.
- Add a model-validation unit test that enumerates indexes and fails if any full-text index has >1 property.
When it happens
Trigger: Calling HasFullTextIndex on an EntityTypeBuilder with more than one property argument, e.g. builder.HasIndex(x => new { x.Title, x.Body }).HasFullTextIndex(). The validator runs during model finalization when ValidateFullTextIndex inspects index.Properties.Count.
Common situations: Developers used to relational composite indexes assume Cosmos full-text search supports multi-column indexes. Migrating from SQL Server full-text (which allows multiple columns) to Cosmos without restructuring the index definitions.
Related errors
- A full-text index is defined for `{entityType}.{property}`,
- The property '{propertyType} {structuralType}.{property}' ha
- The entity type '{entityType}' has property '{property}' con
- The type of the etag property '{property}' on '{entityType}'
- Trigger '{trigger}' is defined on entity type '{entityType}'
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/5ec1c6005a197581.
Report an issue: GitHub.