dotnet/efcore · error · InvalidOperationException
A vector index on '{entityType}' is defined over properties
Error message
A vector index on '{entityType}' is defined over properties `{properties}`. A vector index can only target a single property. What it means
Thrown by ValidateVectorIndex (reached via ValidateIndex when index.GetVectorIndexType() != null) when the vector index spans more than one property. Azure Cosmos DB vector indexes target a single vector property, so a composite vector index is rejected at model validation.
Source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:614
{
// Cosmos maps every property to JSON; no additional validation is needed here.
}
/// <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 ValidateVectorIndex(
IIndex index,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var entityType = index.DeclaringEntityType;
if (index.Properties.Count > 1)
{
throw new InvalidOperationException(
CosmosStrings.CompositeVectorIndex(
entityType.DisplayName(),
string.Join(",", index.Properties.Select(e => e.Name))));
}
if (index.Properties[0] is not IProperty firstVectorIndexProperty
|| firstVectorIndexProperty.GetVectorDistanceFunction() == null
|| firstVectorIndexProperty.GetVectorDimensions() == null)
{
throw new InvalidOperationException(
CosmosStrings.VectorIndexOnNonVector(
entityType.DisplayName(),
index.Properties[0].Name));
}
}
/// <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 composite vector index into one single-property vector index per vector property.
- Declare each vector index over exactly one property: HasIndex(e => e.Vec1).IsVectorIndex(Type, ...).
Example fix
// before
modelBuilder.Entity<Doc>()
.HasIndex(d => new { d.TitleVector, d.BodyVector })
.IsVectorIndex(VectorIndexType.DiskANN);
// after
modelBuilder.Entity<Doc>().HasIndex(d => d.TitleVector).IsVectorIndex(VectorIndexType.DiskANN);
modelBuilder.Entity<Doc>().HasIndex(d => d.BodyVector).IsVectorIndex(VectorIndexType.DiskANN); Defensive patterns
Strategy: validation
Validate before calling
using var ctx = new MyContext();
foreach (var e in ctx.Model.GetEntityTypes())
{
foreach (var idx in e.GetDeclaredIndexes().Where(i => i.GetVectorIndexType() is not null))
{
Debug.Assert(idx.Properties.Count == 1, $"{e.Name}: vector index over [{string.Join(",", idx.Properties.Select(p => p.Name))}] must target a single property");
}
} Try / catch
try { ctx.Model.GetModel(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("vector index can only target a single property"))
{
logger.LogError(ex, "A composite vector index was declared");
throw;
} Prevention
- Declare one vector index per vector property, never a composite.
- Add a test asserting every vector index has exactly one property.
- Do not reuse relational composite-index patterns for vector properties.
When it happens
Trigger: Declaring modelBuilder.Entity<E>().HasIndex(e => new { e.Vec1, e.Vec2 }).IsVectorIndex(...) or otherwise composing a vector index over multiple properties.
Common situations: Copying a composite relational index pattern onto vector properties; attempting to index multiple embeddings in one index; misunderstanding that each vector index is single-property.
Related errors
- A vector index is defined for `{entityType}.{property}`, but
- The time to live for analytical store was configured to '{tt
- The default time to live was configured to '{ttl1}' on '{ent
- The provisioned throughput was configured to '{throughput1}'
- The provisioned throughput was configured as manual on '{man
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/3528b7b620d21214.
Report an issue: GitHub.