dotnet/efcore · error · InvalidOperationException

'UseChangeTrackingProxies' and 'UseLazyLoadingProxies' each…

Error message

'UseChangeTrackingProxies' and 'UseLazyLoadingProxies' each require 'AddEntityFrameworkProxies' to be called on the internal service provider used.

What it means

Thrown by ProxyFactory.CreateLazyLoadingProxy when IDbContextOptions has no ProxiesOptionsExtension — i.e. neither UseLazyLoadingProxies nor UseChangeTrackingProxies was configured on the DbContext options for this context. The lazy-loading proxy path needs the proxies extension registered in the options pipeline.

Solutions

  1. Call optionsBuilder.UseLazyLoadingProxies() (or UseChangeTrackingProxies) in the DbContext configuration.
  2. Ensure the same DbContextOptions instance that has the proxies extension is passed to the DbContext constructor / AddDbContext.
  3. If using an internal service provider, also call AddEntityFrameworkProxies() on it.

Example fix

// before
optionsBuilder.UseSqlServer(connStr);
// later: factory.CreateLazyLoadingProxy(...) throws

// after
optionsBuilder
    .UseSqlServer(connStr)
    .UseLazyLoadingProxies();
Defensive patterns

Strategy: validation

Validate before calling

// Confirm proxies are configured before invoking lazy-loading proxy creation
var ext = context.GetService<IDbContextOptions>().FindExtension<ProxiesOptionsExtension>();
if (ext == null)
    throw new InvalidOperationException("Call UseLazyLoadingProxies()/UseChangeTrackingProxies() on DbContextOptions.");
// safe to create lazy-loading proxy

Type guard

static bool ProxiesEnabled(DbContext c)
    => c.GetService<IDbContextOptions>().FindExtension<ProxiesOptionsExtension>() != null;

Prevention

When it happens

Trigger: CreateLazyLoadingProxy is invoked (typically through internal/proxy-factory code paths) while the context's DbContextOptions were built without calling UseLazyLoadingProxies() or UseChangeTrackingProxies().

Common situations: Calling proxy creation directly in test or scaffolding code against a context whose options omit the proxies call; configuring proxies on a different DbContextOptions instance than the one used to construct the context; AddDbContext forgot the options lambda that enables proxies.

Related errors


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

Appendix: source

Thrown at src/EFCore.Proxies/Proxies/Internal/ProxyFactory.cs:78

            entityType.ClrType,
            GetInterfacesToProxy(entityType),
            GenerationOptions);

    /// <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 object CreateLazyLoadingProxy(
        DbContext context,
        IEntityType entityType,
        ILazyLoader loader,
        object[] constructorArguments)
    {
        var options = context.GetService<IDbContextOptions>().FindExtension<ProxiesOptionsExtension>();
        return options == null
            ? throw new InvalidOperationException(ProxiesStrings.ProxyServicesMissing)
            : CreateLazyLoadingProxy(entityType, loader, constructorArguments);
    }

    private object CreateLazyLoadingProxy(
        IEntityType entityType,
        ILazyLoader loader,
        object[] constructorArguments)
        => _generator.CreateClassProxy(
            entityType.ClrType,
            GetInterfacesToProxy(entityType),
            GenerationOptions,
            constructorArguments,
            GetNotifyChangeInterceptors(entityType, new LazyLoadingInterceptor(entityType, loader)));

    /// <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

View on GitHub (pinned to 3a2006ef56)