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

Cosmos DB SDK only exposes async APIs (ExecuteItemQueryAsync, ReadItemAsync, etc.). The generated QueryingEnumerable explicitly implements IEnumerator<T> GetEnumerator to throw InvalidOperationException so that any synchronous enumeration (foreach without await, .ToList(), .First()) of a Cosmos query fails fast rather than deadlocking.

Solutions

  1. Use the async equivalents everywhere: ToListAsync, FirstAsync, CountAsync, await foreach with IAsyncEnumerable.
  2. Audit for stray synchronous LINQ operators over Cosmos DbSets.
  3. Configure analyzers to flag sync enumeration on IQueryable.

Example fix

// before
var users = db.Users.ToList();
// after
var users = await db.Users.ToListAsync();
Defensive patterns

Strategy: validation

Validate before calling

// enable CA1849 / analyzers that flag sync-over-async on IQueryable
// in csproj:
// <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" />
// and treat CA1849 as error

Prevention

When it happens

Trigger: Calling a synchronous enumeration API on a Cosmos-backed DbSet: ToList(), First(), Single(), Count(), foreach over the IQueryable, or any LINQ extension that pulls IEnumerator<T>.

Common situations: Copy-pasting relational EF code that uses ToList() into a Cosmos project, legacy sync service code being pointed at Cosmos, or third-party libraries that enumerate synchronously.

Related errors


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

Appendix: source

Thrown at src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs:65

            _querySqlGeneratorFactory = querySqlGeneratorFactory;
            _selectExpression = selectExpression;
            _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();

        private CosmosSqlQuery GenerateQuery()
            => _querySqlGeneratorFactory.Create().GetSqlQuery(
                (SelectExpression)new ParameterInliner(
                        _sqlExpressionFactory,
                        _cosmosQueryContext.Parameters)
                    .Visit(_selectExpression),
                _cosmosQueryContext.Parameters!);

        public string ToQueryString()
        {
            var sqlQuery = GenerateQuery();
            if (sqlQuery.Parameters.Count == 0)
            {
                return sqlQuery.Query;

View on GitHub (pinned to 3a2006ef56)