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

  1. Set HasContainerName on the root entity type of the hierarchy only; remove the configuration from derived types.
  2. If derived types need different containers, they cannot share an inheritance hierarchy with the base type - split them into separate roots.
  3. Audit IEntityTypeConfiguration<T> classes for any ToContainer/HasContainerName calls on derived types and remove them.
  4. 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

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


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)