dotnet/efcore · error · InvalidOperationException
Cosmos automatic-indexing configuration was set on entity…
Error message
Cosmos automatic-indexing configuration was set on entity type '{entityType}', but it must be configured on the document-root entity type '{rootEntityType}' instead. Automatic-indexing settings apply to the container as a whole and are inherited by derived types. What it means
Thrown when an entity type that is NOT a document root (it has a BaseType / is a derived type in the hierarchy) carries an AutomaticIndexingEnabled or AutomaticIndexingExceptions annotation. Cosmos indexing policy is a container-level concern owned by the document root; derived types inherit it and cannot override it locally.
Solutions
- Move the HasAutomaticIndexing / HasAutomaticIndexingExceptions call from the derived type to the document-root entity type.
- If you use IEntityTypeConfiguration<T>, guard the indexing calls with a check that the type is the root (or only register the configuration for the root).
- Search the codebase for HasAutomaticIndexing and verify every call site targets a root entity.
Example fix
// before
modelBuilder.Entity<SpecialOrder>() // derives from Order
.HasAutomaticIndexing(false);
// after
modelBuilder.Entity<Order>() // the document root
.HasAutomaticIndexing(false); Defensive patterns
Strategy: type-guard
Type guard
// Guard: only call HasAutomaticIndexing when configuring a document root.
static bool IsDocumentRoot(Type t, IModel model)
=> model.FindEntityType(t)?.IsDocumentRoot() ?? false;
// usage in OnModelCreating
if (IsDocumentRoot(typeof(Order), modelBuilder.Model))
modelBuilder.Entity<Order>().HasAutomaticIndexing(false); Prevention
- Only configure automatic indexing on document-root entity types.
- Register IEntityTypeConfiguration<T> only for root types when the config includes indexing settings.
- Add a CI test that asserts no derived type carries the AutomaticIndexing annotations.
When it happens
Trigger: A derived entity type (one with a BaseType) calls HasAutomaticIndexing(true/false) or HasAutomaticIndexingExceptions(...). The validator checks FindAnnotation for either name on any non-root type and throws.
Common situations: Applying IEntityTypeConfiguration<T> uniformly to every type in a hierarchy including derived ones; copying a root-type config to a derived type; treating automatic indexing as a per-type setting when it is actually per-container.
Related errors
- A partition key is defined on entity type
- Cosmos automatic indexing is enabled for some entity types…
- 'HasDiscriminatorInJsonId' or…
- 'HasShadowId' was called on a non-root entity type
- The exception list configured for Cosmos automatic indexing…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/f70bf47d9deb3249.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:330
ValidateContainerIndexing(mappedTypes, container);
}
private static void ValidateContainerIndexing(IReadOnlyList<IEntityType> mappedTypes, string container)
{
IEntityType? automaticIndexingOwner = null;
bool? automaticIndexingEnabled = null;
IReadOnlyList<string>? automaticIndexingExceptions = null;
foreach (var entityType in mappedTypes)
{
// Only document-root entity types can carry automatic-indexing configuration.
// The same setting must apply to every entity type in a shared container.
if (entityType.BaseType is not null
&& (entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingEnabled) is not null
|| entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingExceptions) is not null))
{
throw new InvalidOperationException(
CosmosStrings.AutomaticIndexingNotOnRoot(
entityType.DisplayName(),
entityType.GetRootType().DisplayName()));
}
var currentEnabled = entityType.BaseType is null
? (bool?)entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingEnabled)?.Value
: null;
var currentExceptions = entityType.BaseType is null
? (IReadOnlyList<string>?)entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingExceptions)?.Value
: null;
if (currentEnabled is not null || currentExceptions is not null)
{
if (automaticIndexingOwner is null)
{
automaticIndexingOwner = entityType;
automaticIndexingEnabled = currentEnabled;
automaticIndexingExceptions = currentExceptions;View on GitHub (pinned to 3a2006ef56)