dotnet/efcore · error · NotSupportedException

This enumerator cannot be reset.

Error message

This enumerator cannot be reset.

What it means

The QueryingEnumerable enumerator returned by the InMemory shaped-query compiling expression visitor is forward-only. Its Reset() method unconditionally throws NotSupportedException with CoreStrings.EnumerableResetNotSupported. EF Core query result enumerators are designed for single-pass iteration and have no snapshot to rewind to.

Solutions

  1. Replace Reset() + re-iteration with re-executing the query: obtain a fresh enumerator (or re-call the query) for each pass.
  2. Materialize results with ToList()/ToListAsync() if you need multiple iteration passes over the same data.
  3. If a framework forces Reset(), project to a List first and enumerate the list instead of the raw query.

Example fix

// before — manual enumerator with Reset
using var en = ((IEnumerable<Blog>)query).GetEnumerator();
en.MoveNext();
/* ... */
en.Reset();  // throws NotSupportedException
en.MoveNext();

// after — materialize and iterate the list
var list = query.ToList();
var en = list.GetEnumerator();
en.Reset();  // List<T>.Enumerator supports Reset
Defensive patterns

Strategy: validation

Validate before calling

// Never call Reset() on an EF Core query enumerator.
// If multiple passes are needed, materialize to a list first.
var materialized = query.ToList();
var enumerator = materialized.GetEnumerator();
// List<T>.Enumerator.Reset() is supported; EF Core's is not.

Type guard

// Type guard: check if the enumerable is a materialized collection before Reset
static bool CanReset<T>(IEnumerable<T> source)
    => source is IList<T> or ICollection<T> or Array;

// Usage:
if (!CanReset(queryResult))
    queryResult = queryResult.ToList();

Try / catch

try
{
    enumerator.Reset();
}
catch (NotSupportedException ex) when (ex.Message.Contains("cannot be reset"))
{
    // Re-execute the query or iterate a materialized copy
    materialized = query.ToList();
    enumerator = materialized.GetEnumerator();
}

Prevention

When it happens

Trigger: Calling IEnumerator.Reset() on the enumerator obtained by directly iterating an EF Core InMemory query (e.g. via ((IEnumerable<T>)query).GetEnumerator()). This is rare in normal foreach usage but can be triggered by libraries or frameworks that call Reset() on enumerators.

Common situations: Third-party libraries that reset enumerators (e.g. some reporting engines, data adapters, or UI binding frameworks). Manually managing an enumerator and trying to rewind it. Code that shares an enumerator across multiple iteration passes.

Related errors


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

Appendix: source

Thrown at src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs:164

                return hasNext;
            }

            public void Dispose()
            {
                _enumerator?.Dispose();
                _enumerator = null;
            }

            public ValueTask DisposeAsync()
            {
                var enumerator = _enumerator;
                _enumerator = null;

                return enumerator.DisposeAsyncIfAvailable();
            }

            public void Reset()
                => throw new NotSupportedException(CoreStrings.EnumerableResetNotSupported);
        }
    }
}

View on GitHub (pinned to 3a2006ef56)