dotnet/efcore · error · InvalidOperationException
An Azure Cosmos DB container name is defined on entity type
Error message
An Azure Cosmos DB container name is defined on entity type '{entityType}', which inherits from '{baseEntityType}'. Container names must be defined on the root entity type of a hierarchy. What it means
CosmosModelValidator.ValidateSharedContainerCompatibility throws InvalidOperationException(CosmosStrings.ContainerNotOnRoot) when a derived entity type (entityType.BaseType != null) has its own ContainerName annotation. Cosmos requires the container to be declared only on the root entity type of an inheritance hierarchy; setting it on a derived type is ambiguous because the discriminator and container must be consistent across the hierarchy.
Solutions
- Set HasContainerName on the root entity type of the hierarchy only; remove the configuration from derived types.
- If derived types need different containers, they cannot share an inheritance hierarchy with the base type - split them into separate roots.
- Audit IEntityTypeConfiguration<T> classes for any ToContainer/HasContainerName calls on derived types and remove them.
- If configuration is shared via a common base configuration, branch on whether entityType.BaseType is null before applying the container name.
Example fix
// before - throws: derived type sets its own container
class AnimalConfig : IEntityTypeConfiguration<Animal> { /* sets Container=Animals */ }
class DogConfig : IEntityTypeConfiguration<Dog>
{
public void Configure(EntityTypeBuilder<Dog> b)
=> b.HasContainerName("Dogs"); // Dog derives from Animal
}
// after - only the root sets the container
class DogConfig : IEntityTypeConfiguration<Dog>
{
public void Configure(EntityTypeBuilder<Dog> b) { /* no HasContainerName */ }
} Defensive patterns
Strategy: validation
Validate before calling
// Only set container name on root entity types.
static void SetContainer<T>(EntityTypeBuilder<T> b, string name) where T : class
{
if (b.Metadata.BaseType is not null)
throw new InvalidOperationException($"Set container on {b.Metadata.BaseType.DisplayName()} instead.");
b.HasContainerName(name);
} Type guard
static bool IsRootEntityType(IEntityType et) => et.BaseType is null;
Prevention
- Set HasContainerName on the root entity of a hierarchy only.
- Audit IEntityTypeConfiguration<T> classes for ToContainer/HasContainerName on derived types.
- Do not copy container configuration down an inheritance chain in shared conventions.
- Validate the model at startup so misconfiguration surfaces early.
When it happens
Trigger: Calling HasContainerName("X") on a derived entity in a TPH hierarchy; configuring [Container("X")] on a subclass; setting ToContainer on a derived type while the base type has its own container.
Common situations: Migrating from per-type configuration to TPH and forgetting to remove the container name on derived types; using ApplyConfigurationsFromAssembly where an IEntityTypeConfiguration<T> for a derived type sets the container; conventions that copy container names down an inheritance chain.
Related errors
- The entity type ' ' is mapped to the container ' ' but it…
- The entity type ' ' is owned by the entity type ' ', but is…
- Both ' ' and ' ' are explicitly mapped to the stored…
- Both ' ' and ' ' are mapped to the table ' '. All the…
- Both ' ' and ' ' are mapped to the stored procedure ' '…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/0bc1c6ff7cfd0788.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:92
/// </summary>
protected virtual void ValidateSharedContainerCompatibility(
IModel model,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
// All entity types mapped to a single container must have the same container-level settings, most notably partition keys.
var containers = new Dictionary<string, List<IEntityType>>();
foreach (var entityType in model.GetEntityTypes().Where(et => et.FindPrimaryKey() != null))
{
var container = entityType.GetContainer();
if (container == null)
{
continue;
}
if (entityType.BaseType != null
&& entityType.FindAnnotation(CosmosAnnotationNames.ContainerName)?.Value != null)
{
throw new InvalidOperationException(
CosmosStrings.ContainerNotOnRoot(entityType.DisplayName(), entityType.BaseType.DisplayName()));
}
var ownership = entityType.FindOwnership();
if (ownership != null)
{
throw new InvalidOperationException(
CosmosStrings.OwnedTypeDifferentContainer(
entityType.DisplayName(),
ownership.PrincipalEntityType.DisplayName(),
container));
}
if (entityType.GetContainingPropertyName() != null)
{
throw new InvalidOperationException(
CosmosStrings.ContainerContainingPropertyConflict(
entityType.DisplayName(),View on GitHub (pinned to 3a2006ef56)