dotnet/efcore · error · OperationException

The provider ' ' is not a Relational provider and therefore…

Error message

The provider '{provider}' is not a Relational provider and therefore cannot be used with Migrations.

What it means

EnsureServices verifies that a relational IMigrator is registered in the design-time service provider. If only a non-relational provider is active (e.g. the in-memory provider), IDatabaseProvider is non-relational and there is no IMigrator, so migrations cannot be generated or applied. The message reports the provider's Name (or 'Unknown' if IDatabaseProvider itself is absent).

Solutions

  1. Configure a relational provider in your DbContext (UseSqlServer, UseNpgsql, UseSqlite, UseMySql, etc.) at design time.
  2. Ensure the design-time context (the one EF tools instantiate) is the production/relational one, not a test context using InMemory.
  3. If you have multiple contexts, pass the correct --context that uses a relational provider.

Example fix

// before
optionsBuilder.UseInMemoryDatabase("tests");
// after
optionsBuilder.UseSqlServer(connectionString);
Defensive patterns

Strategy: validation

Validate before calling

var provider = dbContextOptions.Extensions.OfType<CoreOptionsExtension>().FirstOrDefault();
var isRelational = dbContextOptions.Extensions.OfType<RelationalOptionsExtension>().Any();
if (!isRelational)
{
    throw new InvalidOperationException("A relational provider is required for migrations.");
}

Try / catch

try { operations.AddMigration(...); }
catch (OperationException ex) when (ex.Message.Contains("not a Relational provider"))
{ /* switch from InMemory to SqlServer/Sqlite/etc. */ }

Prevention

When it happens

Trigger: Calling any migration operation that runs EnsureServices (the migrations path of AddMigration/RemoveMigration/etc.) when the configured database provider is not relational. Examples: UseInMemoryDatabase, or a provider whose Name does not indicate relational support, leaving services.GetService<IMigrator>() null.

Common situations: Running 'dotnet ef migrations add' against a DbContext configured with UseInMemoryDatabase() (often used in tests); a test/seed context accidentally selected as the design-time context; misconfigured OnConfiguring pointing at a non-relational provider.

Related errors


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

Appendix: source

Thrown at src/EFCore.Design/Design/Internal/MigrationsOperations.cs:469

        if (string.Equals(name, contextClassName, StringComparison.Ordinal))
        {
            throw new OperationException(
                DesignStrings.ConflictingContextAndMigrationName(name));
        }

        var services = _servicesBuilder.Build(context);
        EnsureServices(services);

        return services;
    }

    private static void EnsureServices(IServiceProvider services)
    {
        var migrator = services.GetService<IMigrator>();
        if (migrator == null)
        {
            var databaseProvider = services.GetService<IDatabaseProvider>();
            throw new OperationException(DesignStrings.NonRelationalProvider(databaseProvider?.Name ?? "Unknown"));
        }
    }

    private void EnsureMigrationsAssembly(IServiceProvider services)
    {
        var assemblyName = _assembly.GetName();
        var options = services.GetRequiredService<IDbContextOptions>();
        var contextType = services.GetRequiredService<ICurrentDbContext>().Context.GetType();
        var optionsExtension = RelationalOptionsExtension.Extract(options);
        if (optionsExtension.MigrationsAssemblyObject == null
            || optionsExtension.MigrationsAssemblyObject != _assembly)
        {
            var migrationsAssemblyName = optionsExtension.MigrationsAssembly
                ?? optionsExtension.MigrationsAssemblyObject?.GetName().Name
                ?? contextType.Assembly.GetName().Name;
            if (assemblyName.Name != migrationsAssemblyName
                && assemblyName.FullName != migrationsAssemblyName)
            {

View on GitHub (pinned to 3a2006ef56)