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
Identical to the standard Cosmos sync-not-supported guard, but thrown specifically by the ReadItem-query path (ReadItemQueryingEnumerable.GetEnumerator). The ReadItem optimization performs a point read via the Cosmos SDK, which is async-only, so synchronous enumeration is blocked.
Source
Thrown at src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs:62
_rootEntityType = rootEntityType;
_readItemInfo = readItemInfo;
_shaper = shaper;
_contextType = contextType;
_queryLogger = _cosmosQueryContext.QueryLogger;
_standAloneStateManager = standAloneStateManager;
_threadSafetyChecksEnabled = threadSafetyChecksEnabled;
_cosmosContainer = rootEntityType.GetContainer()
?? throw new UnreachableException("Root entity type without a Cosmos container.");
_cosmosPartitionKey = GeneratePartitionKey(
rootEntityType, partitionKeyPropertyValues, _cosmosQueryContext.Parameters);
}
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
=> new AsyncEnumerator(this, cancellationToken);
public IEnumerator<T> GetEnumerator()
=> throw new InvalidOperationException(CosmosStrings.SyncNotSupported);
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public string ToQueryString()
{
TryGetResourceId(out var resourceId);
return CosmosStrings.NoReadItemQueryString(resourceId, _cosmosPartitionKey);
}
private bool TryGetResourceId(out string resourceId)
{
var jsonIdDefinition = _rootEntityType.GetJsonIdDefinition();
Check.DebugAssert(
jsonIdDefinition != null,
"Should not be using this enumerable if not using ReadItem, which needs an id definition.");
var values = new List<object>(jsonIdDefinition.Properties.Count);View on GitHub (pinned to dbf9771522)
Solutions
- Use async APIs: FirstAsync, SingleAsync, ToListAsync on the query.
- Ensure the consuming layer is async all the way up.
- Verify no synchronous helper enumerates the result before returning to an async context.
Example fix
// before var blog = context.Blogs.WithPartitionKey(pk).Where(b => b.Id == id).First(); // after var blog = await context.Blogs.WithPartitionKey(pk).Where(b => b.Id == id).FirstAsync();
Defensive patterns
Strategy: validation
Validate before calling
// Use async point-read APIs only
public async Task<Blog?> FindAsync(string pk, string id)
=> await context.Blogs.WithPartitionKey(pk).Where(b => b.Id == id).FirstOrDefaultAsync(); Prevention
- Use FirstAsync/SingleAsync for point-read queries on Cosmos.
- Audit repository methods to ensure none call sync LINQ on Cosmos queries.
- Enable blocking-sync detection (configure context options) in development.
When it happens
Trigger: Triggering a point-read (ReadItem) optimized query and then enumerating it synchronously (ToList, First, foreach). ReadItem optimization kicks in for PK lookups like Where(b => b.Id == id) combined with partition key.
Common situations: A query that the provider optimizes to a ReadItem (single document point read) being consumed via sync LINQ. Migrating a relational GetById that used First() synchronously.
Related errors
- Azure Cosmos DB does not support synchronous I/O. Make sure
- Unable to generate a valid 'id' value to execute a 'ReadItem
- Unable to execute a 'ReadItem' query since the 'id' value is
- The LINQ expression '{expression}' could not be translated.
- Including navigation '{navigation}' is not supported as the
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/e26574f5061c5e97.
Report an issue: GitHub.