dotnet/efcore · critical · InvalidOperationException

Multiple relational database provider configurations found.

Error message

Multiple relational database provider configurations found. A context can only be configured to use a single database provider.

What it means

Thrown by RelationalOptionsExtension.Extract(IDbContextOptions) at line 424 when more than one RelationalOptionsExtension is registered in the context options. EF only allows a single relational provider per context because each provider registers conflicting singleton services. The Count check `relationalOptionsExtensions.Count > 1` fires.

Source

Thrown at src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs:424

    /// <summary>
    ///     Finds an existing <see cref="RelationalOptionsExtension" /> registered on the given options
    ///     or throws if none has been registered. This is typically used to find some relational
    ///     configuration when it is known that a relational provider is being used.
    /// </summary>
    /// <param name="options">The context options to look in.</param>
    /// <returns>The extension.</returns>
    public static RelationalOptionsExtension Extract(IDbContextOptions options)
    {
        var relationalOptionsExtensions
            = options.Extensions
                .OfType<RelationalOptionsExtension>()
                .ToList();

        return relationalOptionsExtensions.Count == 0
            ? throw new InvalidOperationException(RelationalStrings.NoProviderConfigured)
            : relationalOptionsExtensions.Count > 1
                ? throw new InvalidOperationException(RelationalStrings.MultipleProvidersConfigured)
                : relationalOptionsExtensions[0];
    }

    /// <summary>
    ///     Adds the services required to make the selected options work. This is used when there
    ///     is no external <see cref="IServiceProvider" /> and EF is maintaining its own service
    ///     provider internally. This allows database providers (and other extensions) to register their
    ///     required services when EF is creating a service provider.
    /// </summary>
    /// <param name="services">The collection to add services to.</param>
    public abstract void ApplyServices(IServiceCollection services);

    /// <summary>
    ///     Gives the extension a chance to validate that all options in the extension are valid.
    ///     Most extensions do not have invalid combinations and so this will be a no-op.
    ///     If options are invalid, then an exception should be thrown.
    /// </summary>
    /// <param name="options">The options being validated.</param>

View on GitHub (pinned to dbf9771522)

Solutions

  1. Remove all but one provider registration call from OnConfiguring / AddDbContext.
  2. If selecting a provider at runtime, ensure only one branch executes (use else-if or a switch with a single call).
  3. Check for a base class OnConfiguring that already registers a provider before calling another in the derived class.

Example fix

// before: two providers registered
protected override void OnConfiguring(DbContextOptionsBuilder o)
{
    o.UseSqlServer(connStr);
    o.UseSqlite(connStr); // duplicate
}

// after
protected override void OnConfiguring(DbContextOptionsBuilder o)
{
    o.UseSqlServer(connStr);
}
Defensive patterns

Strategy: validation

Validate before calling

var providerExts = context.Database.GetService<IDbContextOptions>().Extensions
    .OfType<Microsoft.EntityFrameworkCore.Infrastructure.RelationalOptionsExtension>().ToList();
if (providerExts.Count > 1) throw new InvalidOperationException($"{providerExts.Count} relational providers registered — expected 1.");

Prevention

When it happens

Trigger: Calling two provider registration methods on the same DbContext, e.g., optionsBuilder.UseSqlServer(connStr).UseSqlite(connStr). Or mixing UseNpgsql with UseSqlServer in different OnConfiguring paths that both execute.

Common situations: Copy-paste errors leaving two UseXxx calls. Provider switching where the old call wasn't removed. DI configuration that conditionally adds providers but the condition evaluates true for multiple branches. Integration test base classes that call UseInMemoryDatabase on top of a real provider.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/d3a93654e36fff31. Report an issue: GitHub.