dotnet/efcore · error · InvalidOperationException

The provisioned throughput was configured as manual on '{man

Error message

The provisioned throughput was configured as manual on '{manualEntityType}', but on '{autoscaleEntityType}' it was configured as autoscale. All entity types mapped to the same container '{container}' must be configured with the same provisioned throughput type.

What it means

Thrown by CosmosModelValidator.ValidateSharedContainerCompatibility when two root entities in the same container agree on the throughput RU number but disagree on whether it is manual vs autoscale. The validator reaches this branch only after the numeric values match, then checks throughput.AutoscaleMaxThroughput == null on one side and not the other. Cosmos requires a single throughput mode per container.

Source

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

                            throughput.AutoscaleMaxThroughput ?? throughput.Throughput,
                            conflictingEntityType.DisplayName(),
                            entityType.DisplayName(),
                            currentThroughput.AutoscaleMaxThroughput ?? currentThroughput.Throughput,
                            container));
                }
                else if (throughput.AutoscaleMaxThroughput
                         == null
                         != (currentThroughput.AutoscaleMaxThroughput == null))
                {
                    var conflictingEntityType = mappedTypes.First(et => et.GetThroughput() != null);
                    var autoscaleType = throughput.AutoscaleMaxThroughput == null
                        ? entityType
                        : conflictingEntityType;
                    var manualType = throughput.AutoscaleMaxThroughput != null
                        ? entityType
                        : conflictingEntityType;

                    throw new InvalidOperationException(
                        CosmosStrings.ThroughputTypeMismatch(manualType.DisplayName(), autoscaleType.DisplayName(), container));
                }
            }
        }

        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.

View on GitHub (pinned to dbf9771522)

Solutions

  1. Use the same autoscale flag (true or false) on every root entity in the container, keeping the RU value identical.
  2. Centralize the throughput+autoscale choice in one config call applied to all roots.
  3. Remove redundant HasThroughput calls so only one entity declares it.

Example fix

// before
modelBuilder.Entity<Invoice>().ToContainer("billing").HasThroughput(1000, autoscale: true);
modelBuilder.Entity<Receipt>().ToContainer("billing").HasThroughput(1000, autoscale: false);

// after
modelBuilder.Entity<Invoice>().ToContainer("billing").HasThroughput(1000, autoscale: true);
modelBuilder.Entity<Receipt>().ToContainer("billing").HasThroughput(1000, autoscale: true);
Defensive patterns

Strategy: validation

Validate before calling

using (var ctx = new MyContext()) { ctx.Model.GetModel(); }
foreach (var grp in ctx.Model.GetEntityTypes()
    .Where(e => e.FindPrimaryKey() != null && e.GetContainer() != null)
    .GroupBy(e => e.GetContainer()))
{
    var modes = grp.Select(e => e.GetThroughput()?.AutoscaleMaxThroughput is null ? "manual" : "autoscale").Distinct().ToList();
    Debug.Assert(modes.Count <= 1, $"Container {grp.Key} mixes manual/autoscale throughput");
}

Try / catch

try { ctx.Model.GetModel(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("configured as manual"))
{
    logger.LogError(ex, "Throughput type (manual vs autoscale) mismatch in shared container");
    throw;
}

Prevention

When it happens

Trigger: Calling HasThroughput(1000, autoscale: true) on one entity and HasThroughput(1000, autoscale: false) on another entity mapped to the same container.

Common situations: Migrating from manual to autoscale provisioning but only updating one entity; copy-paste where the autoscale flag was dropped; a config helper that defaults autoscale differently per caller.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/dc317d87a52679af. Report an issue: GitHub.