dotnet/efcore · error · InvalidOperationException
The index over properties '{properties}' is declared on owne
Error message
The index over properties '{properties}' is declared on owned type '{ownedEntityType}', which is mapped to container '{containerEntityType}'. Indexes that traverse owned types are not currently supported. What it means
Thrown by ValidateContainerIndexing while walking the owned-type tree (EnumerateContainerIndexes) when a regular (non-vector, non-full-text) index is declared on an owned entity type. The validator walks ownership navigations from each document root; any HasIndex declared on a non-document-root type that is not a vector or full-text index is rejected, because Cosmos indexes cannot traverse embedded owned documents in the relational sense.
Source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:389
throw new InvalidOperationException(
CosmosStrings.InconsistentAutomaticIndexing(
container,
automaticIndexingOwner.DisplayName(),
entityType.DisplayName()));
}
}
}
// Walk the full owned/complex tree to surface every HasIndex declared in this container.
// Vector and full-text indexes are allowed to traverse owned types; only regular indexes are
// rejected
foreach (var (declaringEntityType, index) in EnumerateContainerIndexes(entityType))
{
if (!declaringEntityType.IsDocumentRoot()
&& index.GetVectorIndexType() == null
&& index.IsFullTextIndex() != true)
{
throw new InvalidOperationException(
CosmosStrings.IndexOnOwnedType(
string.Join(",", index.Properties.Select(e => e.Name)),
declaringEntityType.DisplayName(),
entityType.DisplayName()));
}
}
}
}
private static IEnumerable<(IEntityType DeclaringEntityType, IIndex Index)> EnumerateContainerIndexes(IEntityType root)
{
foreach (var index in root.GetIndexes())
{
yield return (root, index);
}
foreach (var ownedNav in root.GetNavigations()
.Where(n => n.ForeignKey.IsOwnership && !n.IsOnDependent && !n.TargetEntityType.IsDocumentRoot()))View on GitHub (pinned to dbf9771522)
Solutions
- Remove the HasIndex from the owned type.
- If you need to query by the nested value, declare the index on the document-root entity over the flattened path, or restructure the property onto the root.
- If the index is genuinely a vector or full-text index, use the vector/full-text APIs which are allowed to traverse owned types.
Example fix
// before
modelBuilder.Entity<Customer>().OwnsOne(c => c.Address, a =>
{
a.HasIndex(x => x.PostalCode); // Address is owned -> rejected
});
// after
modelBuilder.Entity<Customer>().OwnsOne(c => c.Address);
// query by the nested JSON path directly; no HasIndex on the owned type Defensive patterns
Strategy: validation
Validate before calling
using var ctx = new MyContext();
foreach (var root in ctx.Model.GetEntityTypes().Where(e => e.FindPrimaryKey() != null))
{
foreach (var nav in root.GetNavigations().Where(n => n.ForeignKey.IsOwnership && !n.IsOnDependent))
{
foreach (var idx in nav.TargetEntityType.GetIndexes())
{
var isVector = idx.GetVectorIndexType() is not null;
var isFullText = idx.IsFullTextIndex() == true;
Debug.Assert(isVector || isFullText,
$"Index [{string.Join(",", idx.Properties.Select(p => p.Name))}] on owned {nav.TargetEntityType.Name} is not allowed (only vector/full-text may traverse owned types).");
}
}
} Try / catch
try { ctx.Model.GetModel(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Indexes that traverse owned types are not currently supported"))
{
logger.LogError(ex, "A regular HasIndex was declared on an owned type");
throw;
} Prevention
- Do not declare regular HasIndex on owned entity types; declare indexes on the document root.
- Use vector (.IsVectorIndex) or full-text (.IsFullTextSearch) indexes if you must index across owned types.
- When porting relational models, audit every HasIndex inside OwnsOne/OwnsMany blocks.
When it happens
Trigger: Calling modelBuilder.Entity<Owner>().OwnsOne(o => o.Address, a => a.HasIndex(x => x.Zip)) where Address is an owned type embedded in the Owner document. Regular indexes on owned types are unsupported; only vector and full-text indexes may cross the ownership boundary.
Common situations: Porting a relational model that indexed properties now nested inside owned types; wanting to 'speed up' lookups on a nested value; treating owned types like separate tables.
Related errors
- Cosmos automatic-indexing configuration was set on entity ty
- Cosmos automatic indexing is enabled for some entity types b
- The exception list configured for Cosmos automatic indexing
- The entity type '{entityType}' is owned by the entity type '
- The entity type '{entityType}' is mapped to the container '{
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/b76d4114bd841baa.
Report an issue: GitHub.