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
- Keep exactly one UseXxx call per DbContext options build; remove the duplicate.
- Branch with if/else or a switch on environment/config so only one provider is registered.
- 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
- Keep exactly one UseXxx call per options build; remove duplicates.
- Branch provider selection with if/else so only one registers per environment.
- Use separate DbContext types if you truly need two providers.
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
- No relational database providers are configured. Configure…
- Relational-specific methods can only be used when the…
- The provider ' ' is not a Relational provider and therefore…
- The parameter ' ' for the DbFunction ' ' has an invalid…
- The specified 'CommandTimeout' value
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)