dotnet/efcore · error · 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

RelationalOptionsExtension.Extract throws MultipleProvidersConfigured when more than one RelationalOptionsExtension is found in options.Extensions. A single DbContext may use exactly one relational provider; chaining two UseXxx calls (or adding two provider extensions) is ambiguous.

Solutions

  1. Keep exactly one UseXxx call per DbContext options build; remove the duplicate.
  2. Branch with if/else or a switch on environment/config so only one provider is registered.
  3. If you need two providers, use two separate DbContext types / options instances.

Example fix

// before
optionsBuilder.UseSqlServer(conn);
optionsBuilder.UseNpgsql(conn); // -> [451]

// after — pick one based on configuration
if (usePostgres)
{
    optionsBuilder.UseNpgsql(conn);
}
else
{
    optionsBuilder.UseSqlServer(conn);
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure at most one relational provider is registered.
static int RelationalProviderCount(IDbContextOptions options)
    => options.Extensions.OfType<RelationalOptionsExtension>().Count();

Prevention

When it happens

Trigger: Calling two provider registrations on the same options builder, e.g. optionsBuilder.UseSqlServer(...).UseNpgsql(...), or UseSqlite(...) followed by UseSqlServer(...). Also AddDbContext chain that conditionally adds two providers.

Common situations: Accidentally stacking provider calls; mixing a test provider (SQLite) with a production one (SQL Server) in the same configuration branch; copy-paste between environments.

Related errors


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

Appendix: 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 3a2006ef56)