dotnet/efcore · error · NotSupportedException
User transaction is not supported with a TransactionSuppress
Error message
User transaction is not supported with a TransactionSuppressed migrations or a retrying execution strategy.
What it means
Thrown by Migrator.ValidateMigrations when `Migrate`/`MigrateAsync` would run without a transaction (because a user transaction is already on the connection) while the configured execution strategy retries on failure. Retrying migrations need a transaction EF controls; an ambient user transaction makes that impossible.
Source
Thrown at src/EFCore.Relational/Migrations/Internal/Migrator.cs:374
state.DatabaseLock?.Dispose();
state.DatabaseLock = null;
if (state.Transaction != null)
{
await state.Transaction.DisposeAsync().ConfigureAwait(false);
state.Transaction = null;
}
await _connection.CloseAsync().ConfigureAwait(false);
}
}
private void ValidateMigrations(bool useTransaction, string? targetMigration)
{
if (!useTransaction
&& _executionStrategy.RetriesOnFailure)
{
throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction);
}
if (_migrationsAssembly.Migrations.Count == 0)
{
_logger.MigrationsNotFound(this, _migrationsAssembly);
}
else if (_migrationsAssembly.ModelSnapshot == null)
{
_logger.ModelSnapshotNotFound(this, _migrationsAssembly);
}
else if (targetMigration == null
&& RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore
&& HasPendingModelChanges())
{
var modelSource = (ModelSource)_currentContext.Context.GetService<IModelSource>();
#pragma warning disable EF1001 // Internal EF Core API usage.
var newDesignTimeModel = modelSource.CreateModel(
_currentContext.Context, _currentContext.Context.GetService<ModelCreationDependencies>(), designTime: true);View on GitHub (pinned to dbf9771522)
Solutions
- Run `Migrate`/`MigrateAsync` before opening any transaction so EF owns the migration transaction.
- Drop the retrying execution strategy if you must keep the manual transaction.
- Use a separate DbContext/connection scope dedicated to migration.
- Avoid combining `EnableRetryOnFailure` with caller-managed transactions.
Example fix
// before options.UseSqlServer(cs).EnableRetryOnFailure(); using var tx = db.Database.BeginTransaction(); db.Database.Migrate(); // after options.UseSqlServer(cs).EnableRetryOnFailure(); db.Database.Migrate(); using var tx = db.Database.BeginTransaction();
Defensive patterns
Strategy: validation
Validate before calling
// Before Migrate with a retrying strategy, ensure no ambient transaction.
if (db.Database.CurrentTransaction is not null)
throw new InvalidOperationException("Commit/close the ambient transaction before migrating with a retrying strategy.");
db.Database.Migrate(); Prevention
- Run `Migrate`/`MigrateAsync` outside any user transaction when `EnableRetryOnFailure` is configured.
- Use a dedicated DbContext for migration in startup.
- Do not wrap migration in a business transaction.
When it happens
Trigger: Opening your own transaction on the DbContext's connection and then calling `Migrate`/`MigrateAsync` while a retrying execution strategy (e.g. `EnableRetryOnFailure()`) is configured.
Common situations: Hosting code that wraps `Migrate` in a business transaction; transient-fault-handling configured globally with retries plus manual transactions; shared connection used for migrate + work.
Related errors
- User transaction is not supported with a TransactionSuppress
- Relational-specific methods can only be used when the contex
- The default value has not been specified for the column '{ta
- The default value SQL has not been specified for the column
- The computed column SQL has not been specified for the colum
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/23e61ac947ce6b10.
Report an issue: GitHub.