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 synchronous SaveChanges() override (CosmosDatabaseWrapper.cs:628-629) unconditionally throws because all Cosmos DB write operations (create, replace, delete) are asynchronous via the Microsoft.Azure.Cosmos SDK. There is no synchronous write path. This prevents deadlocks from sync-over-async wrapping.
Source
Thrown at src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs:629
private sealed class CosmosUpdateEntry
{
public required IUpdateEntry Entry { get; init; }
public required CosmosCudOperation Operation { get; init; }
public required string CollectionId { get; init; }
public required CosmosStructuralTypeSerializer Serializer { get; init; }
}
private sealed record Grouping(string ContainerId, PartitionKey PartitionKeyValue);
/// <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 override int SaveChanges(IList<IUpdateEntry> entries)
=> throw new InvalidOperationException(CosmosStrings.SyncNotSupported);
}
View on GitHub (pinned to dbf9771522)
Solutions
- Use the async overload: await context.SaveChangesAsync().
- Make all repository/service methods async Task and propagate await up the call stack.
- Refactor sync callers to async; avoid .GetAwaiter().GetResult() or .Result which can deadlock.
Example fix
// before
public void Save(Blog blog)
{
_context.Blogs.Add(blog);
_context.SaveChanges();
}
// after
public async Task SaveAsync(Blog blog)
{
_context.Blogs.Add(blog);
await _context.SaveChangesAsync();
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure SaveChangesAsync is used. Enforce via async repository patterns.
if (context.Database.ProviderName == "Microsoft.EntityFrameworkCore.Cosmos")
{
// always: await context.SaveChangesAsync();
} Prevention
- Make all repository and service methods async Task.
- Never call SaveChanges() (sync) on a Cosmos context.
- Run a code-analysis check for sync SaveChanges calls on Cosmos DbContexts.
When it happens
Trigger: Calling context.SaveChanges() (without Async) on a Cosmos-backed DbContext. This directly throws before any entries are processed.
Common situations: Calling SaveChanges from synchronous application code, legacy libraries, or property setters. Copy-pasting relational save patterns. Using a shared repository abstraction with a sync Save method.
Related errors
- Azure Cosmos DB does not support synchronous I/O. Make sure
- Azure Cosmos DB does not support synchronous I/O. Make sure
- Azure Cosmos DB does not support synchronous I/O. Make sure
- A synchronous store management operation was performed and n
- When using AutoTransactionBehavior.Always with the Cosmos DB
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/ec8782675dc55cd7.
Report an issue: GitHub.