dotnet/efcore · error · InvalidOperationException
The default time to live was configured to '{ttl1}' on '{ent
Error message
The default time to live was configured to '{ttl1}' on '{entityType1}', but on '{entityType2}' it was configured to '{ttl2}'. All entity types mapped to the same container '{container}' must be configured with the same default time to live. What it means
Thrown by CosmosModelValidator.ValidateSharedContainerCompatibility when two document-root entity types in the same container declare different default time-to-live values via HasDefaultTimeToLive(). Default TTL is a container-level Cosmos setting, so all entity types sharing a container must specify the same value. Derived types are compared through their root, so this fires only across distinct document roots.
Source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:266
analyticalTtl,
conflictingEntityType.DisplayName(),
entityType.DisplayName(),
currentAnalyticalTtl,
container));
}
}
var currentDefaultTtl = entityType.GetDefaultTimeToLive();
if (currentDefaultTtl != null)
{
if (defaultTtl == null)
{
defaultTtl = currentDefaultTtl;
}
else if (defaultTtl != currentDefaultTtl)
{
var conflictingEntityType = mappedTypes.First(et => et.GetDefaultTimeToLive() != null);
throw new InvalidOperationException(
CosmosStrings.DefaultTTLMismatch(
defaultTtl,
conflictingEntityType.DisplayName(),
entityType.DisplayName(),
currentDefaultTtl,
container));
}
}
var currentThroughput = entityType.GetThroughput();
if (currentThroughput != null)
{
if (throughput == null)
{
throughput = currentThroughput;
}
else if ((throughput.AutoscaleMaxThroughput ?? throughput.Throughput)
!= (currentThroughput.AutoscaleMaxThroughput ?? currentThroughput.Throughput))View on GitHub (pinned to dbf9771522)
Solutions
- Align every root entity mapped to the container on the same HasDefaultTimeToLive(N) value.
- If only one entity should 'own' the container setting, remove HasDefaultTimeToLive from the others.
- Drive container-level options from a single configuration method applied to all shared-container roots.
Example fix
// before
modelBuilder.Entity<Session>().ToContainer("state").HasDefaultTimeToLive(300);
modelBuilder.Entity<Token>().ToContainer("state").HasDefaultTimeToLive(900);
// after
const int ContainerTtl = 300;
modelBuilder.Entity<Session>().ToContainer("state").HasDefaultTimeToLive(ContainerTtl);
modelBuilder.Entity<Token>().ToContainer("state").HasDefaultTimeToLive(ContainerTtl); 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 ttls = grp.Select(e => e.GetDefaultTimeToLive()).Distinct().ToList();
Debug.Assert(ttls.Count <= 1, $"Container {grp.Key} has conflicting default TTLs");
} Try / catch
try { ctx.Model.GetModel(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("default time to live"))
{
logger.LogError(ex, "Default TTL mismatch in shared Cosmos container");
throw;
} Prevention
- Keep TTL configuration in one place per container.
- Add a test that asserts a single distinct GetDefaultTimeToLive per container group.
- Document which entity 'owns' container-level settings for each container.
When it happens
Trigger: Calling HasDefaultTimeToLive(N) with different N on two entity types that resolve to the same container name, surfaced when the model is validated (e.g. first query, EnsureCreated, or dotnet ef database update).
Common situations: One entity configured for time-based document expiry and another in the same container left at a different/no TTL; refactoring an entity into a shared container without copying the TTL setting; environment-specific config where TTL differs by region.
Related errors
- The time to live for analytical store was configured to '{tt
- The provisioned throughput was configured to '{throughput1}'
- The provisioned throughput was configured as manual on '{man
- Cosmos automatic indexing is enabled for some entity types b
- The exception list configured for Cosmos automatic indexing
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/c17cd3e9c4091f17.
Report an issue: GitHub.