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
Azure Cosmos DB full-text indexes can only target a single property path. During container creation (CosmosClientWrapper.cs:198-204), EF Core rejects any index where IsFullTextIndex() is true and Properties.Count exceeds 1. A composite full-text index is not supported by the Cosmos full-text policy schema.
Source
Thrown at src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs:200
{
if (index.Properties.Count > 1)
{
throw new InvalidOperationException(
CosmosStrings.CompositeVectorIndex(
index.DeclaringEntityType.DisplayName(),
string.Join(",", index.Properties.Select(e => e.Name))));
}
vectorIndexes.Add(
new VectorIndexPath { Path = GetJsonPropertyPathFromRoot(index.Properties[0]), Type = vectorIndexType.Value });
continue;
}
if (index.IsFullTextIndex() == true)
{
if (index.Properties.Count > 1)
{
throw new InvalidOperationException(
CosmosStrings.CompositeFullTextIndex(
index.DeclaringEntityType.DisplayName(),
string.Join(",", index.Properties.Select(e => e.Name))));
}
fullTextIndexPaths.Add(
new FullTextIndexPath { Path = GetJsonPropertyPathFromRoot(index.Properties[0]) });
continue;
}
var isConvention = index is IConventionIndex convIndex
&& convIndex.GetConfigurationSource() == ConfigurationSource.Convention;
if (index.Properties.Count == 1)
{
var path = GetJsonPropertyPathFromRoot(index.Properties[0]) + "/?";
if (seenIncludedPaths.Add(path))
{View on GitHub (pinned to dbf9771522)
Solutions
- Create a separate single-property full-text index for each property you want searchable: modelBuilder.Entity<T>().HasIndex(x => x.Title).ForCosmos().IsFullTextIndex(); and modelBuilder.Entity<T>().HasIndex(x => x.Body).ForCosmos().IsFullTextIndex().
- Ensure each full-text index targets exactly one property.
- Recreate the container after fixing the model.
Example fix
// before
modelBuilder.Entity<Article>()
.HasIndex(a => new { a.Title, a.Body })
.ForCosmos()
.IsFullTextIndex();
// after
modelBuilder.Entity<Article>().HasIndex(a => a.Title).ForCosmos().IsFullTextIndex();
modelBuilder.Entity<Article>().HasIndex(a => a.Body).ForCosmos().IsFullTextIndex(); Defensive patterns
Strategy: validation
Validate before calling
// Validate that no full-text index spans multiple properties.
foreach (var entityType in model.GetEntityTypes())
{
foreach (var index in entityType.GetIndexes())
{
if (index.IsFullTextIndex() == true && index.Properties.Count > 1)
throw new InvalidOperationException($"Full-text index on {entityType.DisplayName()} has multiple properties.");
}
} Prevention
- Create one single-property full-text index per searchable column.
- Never combine multiple properties in a HasIndex() when calling IsFullTextIndex().
- Add a model-validation test asserting full-text indexes target exactly one property.
When it happens
Trigger: Configuring an index over multiple properties and enabling full-text search on it, e.g. modelBuilder.Entity<T>().HasIndex([x => x.Title, x => x.Body]).ForCosmos().IsFullTextIndex(). This fires at container-creation time.
Common situations: Wanting to full-text search across multiple text columns and assuming a composite index covers them. Copying a relational composite index and adding IsFullTextIndex(). Confusing full-text index (single property) with composite indexes (general purpose).
Related errors
- A vector index on '{entityType}' is defined over properties
- Creating a container with full-text search or vector propert
- Ordering based on scoring function is not supported inside '
- Only one ordering using scoring function is allowed. Use 'EF
- Ordering using a scoring function is mutually exclusive with
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/cb9996b3cabaa7d7.
Report an issue: GitHub.