dotnet/efcore · error · InvalidOperationException

Azure Cosmos DB does not support synchronous I/O. Make sure

Error message

Azure Cosmos DB does not support synchronous I/O. Make sure to use and correctly await only async methods when using Entity Framework Core to access Azure Cosmos DB.

What it means

The Cosmos DB provider only supports asynchronous I/O because the underlying Microsoft.Azure.Cosmos SDK has no synchronous API surface. The synchronous EnsureCreated() method (CosmosDatabaseCreator.cs:307-308) unconditionally throws InvalidOperationException to prevent deadlocks and force correct async usage. The provider's entire storage layer is async-only.

Source

Thrown at src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs:308

    /// <returns>The names of the partition key property.</returns>
    private static IReadOnlyList<string> GetPartitionKeyStoreNames(IEntityType entityType)
    {
        var properties = entityType.GetPartitionKeyProperties();
        return properties.Any()
            ? properties.Select(p => p.GetJsonPropertyName()).ToList()
            : [CosmosClientWrapper.DefaultPartitionKey];
    }

    #region Unsupported sync methods

    /// <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 bool EnsureCreated()
        => throw new InvalidOperationException(CosmosStrings.SyncNotSupported);

    /// <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 bool EnsureDeleted()
        => throw new InvalidOperationException(CosmosStrings.SyncNotSupported);

    /// <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 bool CanConnect()
        => throw new InvalidOperationException(CosmosStrings.SyncNotSupported);

View on GitHub (pinned to dbf9771522)

Solutions

  1. Use the async overload: await context.Database.EnsureCreatedAsync().
  2. Make the calling method async all the way up; do not use .Result or .Wait() which can deadlock.
  3. If trapped in a sync context, use a top-level async Main (static async Task Main) or an async overload of the host lifecycle method.

Example fix

// before
context.Database.EnsureCreated();

// after
await context.Database.EnsureCreatedAsync();
Defensive patterns

Strategy: validation

Validate before calling

// Ensure EnsureCreatedAsync is used. There is no runtime guard; enforce via code review and async APIs.
// Quick check: if a Cosmos provider is detected, all DB-management calls must be async.
var provider = context.Database.ProviderName;
if (provider == "Microsoft.EntityFrameworkCore.Cosmos")
{
    // never call EnsureCreated(); always await EnsureCreatedAsync()
}

Prevention

When it happens

Trigger: Calling context.Database.EnsureCreated() (no await, no Async suffix) on a Cosmos-backed DbContext. This is the synchronous overload that directly throws before any work is done.

Common situations: Copy-pasting relational code that calls EnsureCreated() synchronously. Calling from a non-async context (e.g., a property getter, a static initializer, Main without async). Forgetting the Async suffix.

Related errors


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