dotnet/efcore · error · InvalidOperationException

The entity type ' ' is owned by the entity type ' ', but is…

Error message

The entity type '{entityType}' is owned by the entity type '{owner}', but is mapped to the container '{container}'. Owned types mapped to a container directly are not supported, remove this configuration to allow the owned type to be embedded in the same document as the owner.

What it means

CosmosModelValidator.ValidateSharedContainerCompatibility throws InvalidOperationException(CosmosStrings.OwnedTypeDifferentContainer) when an entity type that is owned by another entity type (entityType.FindOwnership() != null) is mapped to a Cosmos container directly. Cosmos owned types must be embedded in the same document as their owner; they cannot live in their own container. The validator catches this at model finalization.

Solutions

  1. Remove ToContainer/HasContainerName from the owned entity configuration; let the owned type embed inside the owner's document.
  2. If the entity genuinely needs its own container, change it from owned to a regular entity with a one-to-many or one-to-one relationship.
  3. When iterating entity types to apply container configuration generically, skip types where entityType.FindOwnership() != null.
  4. Audit IEntityTypeConfiguration<T> classes that configure owned types and remove any container-name setters.

Example fix

// before - throws: owned type has its own container
entity.OwnsOne(e => e.Profile, pb =>
{
    pb.ToContainer("Profiles");
});

// after - let the owned type embed in the owner's document
entity.OwnsOne(e => e.Profile);
// or: make Profile a real entity with a relationship, then it can have a container
entity.HasOne(e => e.Profile)
    .WithOne()
    .HasForeignKey<Profile>(p => p.OwnerId);
Defensive patterns

Strategy: validation

Validate before calling

// Skip owned types when applying container configuration generically.
foreach (var et in modelBuilder.Model.GetEntityTypes().Where(e => e.FindOwnership() is null && e.BaseType is null))
{
    modelBuilder.Entity(et.ClrType).HasContainerName("Shared");
}

Type guard

static bool IsOwnedType(IEntityType et) => et.FindOwnership() is not null;

Prevention

When it happens

Trigger: Calling OwnsOne(o => o.Address).ToContainer("Addresses") or OwnsMany(...).HasContainerName(...); configuring an owned entity type with a container name via attribute or IEntityTypeConfiguration; using OwnsOne combined with HasContainerName on the owned type.

Common situations: Porting a relational model where owned types were table-splitting into separate tables and converting them to containers; applying a generic 'configure all entity types set their container' routine that also catches owned types.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/d70dd0e9765cfdcd. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:99

        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(),
                        container,
                        entityType.GetContainingPropertyName()));
            }

            if (!containers.TryGetValue(container, out var mappedTypes))
            {
                mappedTypes = [];

View on GitHub (pinned to 3a2006ef56)