dotnet/efcore · error · InvalidOperationException

No session token has been set for container: '{container}'.

Error message

No session token has been set for container: '{container}'. While using 'EnforceManual' mode you must always set a session token for any container used on every context instance.

What it means

Thrown by SessionTokenStorage.GetSessionToken when operating in SessionTokenManagementMode.EnforcedManual and the requested container has no session token set (IsSet is false). EnforcedManual is intentionally strict: every container touched by a context instance must have an explicitly-provided session token on every instance, so omitting one is treated as a programming error rather than degraded behavior.

Source

Thrown at src/EFCore.Cosmos/Storage/Internal/SessionTokenStorage.cs:166

    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual string? GetSessionToken(string containerName)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(containerName);

        if (_mode == SessionTokenManagementMode.FullyAutomatic)
        {
            return null;
        }

        var sessionToken = _containerSessionTokens[containerName];

        if (!sessionToken.IsSet)
        {
            if (_mode == SessionTokenManagementMode.EnforcedManual)
            {
                throw new InvalidOperationException(CosmosStrings.MissingSessionTokenEnforceManual(containerName));
            }

            if (_mode == SessionTokenManagementMode.SemiAutomatic)
            {
                return null;
            }
        }

        return sessionToken.ConvertToString();
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual void TrackSessionToken(string containerName, string? sessionToken)

View on GitHub (pinned to dbf9771522)

Solutions

  1. Call SetSessionTokens (or TrackSessionToken) for every container the context will use before issuing any operation, in EnforcedManual mode.
  2. If you do not need strict enforcement, downgrade to SemiAutomatic (returns null instead of throwing) or FullyAutomatic.
  3. Enumerate the model's containers (GetTrackedTokens keys) at startup and assert a token is provided for each.

Example fix

// before - EnforcedManual, token missing for 'Orders'
optionsBuilder.UseCosmos(..., o => o.SessionTokenManagementMode(SessionTokenManagementMode.EnforcedManual));
context.Orders.Add(entity); // throws: no token for 'Orders'

// after - seed tokens for all containers first
storage.SetSessionTokens(new Dictionary<string,string?> {
    ["Orders"] = capturedToken,
    ["Customers"] = capturedToken2
});
context.SaveChanges();
Defensive patterns

Strategy: validation

Validate before calling

// In EnforcedManual mode, assert every container has a token before use.
var tracked = sessionTokenStorage.GetTrackedTokens();
var missing = tracked.Where(kv => string.IsNullOrEmpty(kv.Value)).Select(kv => kv.Key).ToList();
if (missing.Count != 0)
    throw new InvalidOperationException($"Missing session tokens for: {string.Join(", ", missing)}");

Try / catch

try { context.SaveChanges(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("No session token has been set"))
{
    // capture and set the token for the named container, then retry
}

Prevention

When it happens

Trigger: Selecting SessionTokenManagementMode.EnforcedManual in Cosmos options and then executing a query or save against a container whose session token was never set via SetSessionTokens/TrackSessionToken. The check fires inside GetSessionToken right before the token would be returned to the Cosmos SDK.

Common situations: Switching from FullyAutomatic or SemiAutomatic to EnforcedManual to enforce consistency guarantees, but forgetting to seed a session token for one or more containers. Adding a new entity/container to the model after enabling EnforcedManual without updating the token-seeding code. Multi-container contexts where only the primary container's token is set.

Related errors


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