dotnet/efcore · error · NotSupportedException

The 'Down' method for this migration has not been implemente

Error message

The 'Down' method for this migration has not been implemented. Both the 'Up' and 'Down' methods must be implemented to support reverting migrations.

What it means

Thrown by the base `Migration.Down(MigrationBuilder)` when a derived migration did not override `Down`. EF requires both `Up` and `Down` to revert migrations; calling rollback/downgrade on a migration with only `Up` implemented throws `NotSupportedException`.

Source

Thrown at src/EFCore.Relational/Migrations/Migration.cs:142

    ///     Builds the operations that will migrate the database 'down'.
    /// </summary>
    /// <remarks>
    ///     <para>
    ///         That is, builds the operations that will take the database from the state left in by
    ///         this migration so that it returns to the state that it was in before this migration was applied.
    ///     </para>
    ///     <para>
    ///         This method must be overridden in each class that inherits from <see cref="Migration" /> if
    ///         both 'up' and 'down' migrations are to be supported. If it is not overridden, then calling it
    ///         will throw and it will not be possible to migrate in the 'down' direction.
    ///     </para>
    ///     <para>
    ///         See <see href="https://aka.ms/efcore-docs-migrations">Database migrations</see> for more information and examples.
    ///     </para>
    /// </remarks>
    /// <param name="migrationBuilder">The <see cref="MigrationBuilder" /> that will build the operations.</param>
    protected virtual void Down(MigrationBuilder migrationBuilder)
        => throw new NotSupportedException(RelationalStrings.MigrationDownMissing);

    private List<MigrationOperation> BuildOperations(Action<MigrationBuilder> buildAction)
    {
        var migrationBuilder = new MigrationBuilder(ActiveProvider);
        buildAction(migrationBuilder);

        return migrationBuilder.Operations;
    }
}

View on GitHub (pinned to dbf9771522)

Solutions

  1. Override `Down(MigrationBuilder)` in the migration class with the reverse operations.
  2. If rollback is not required, migrate forward to a newer migration instead of reverting.
  3. Regenerate the migration with `dotnet ef migrations add` which scaffolds both `Up` and `Down`.

Example fix

// before
public partial class AddFoo : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
        => migrationBuilder.AddColumn<int>("Foo", "Bars");
}
// after
protected override void Down(MigrationBuilder migrationBuilder)
    => migrationBuilder.DropColumn("Foo", "Bars");
Defensive patterns

Strategy: validation

Validate before calling

// Static check: every migration class in the assembly overrides Down.
foreach (var type in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(Migration).IsAssignableFrom(t) && !t.IsAbstract))
{
    var down = type.GetMethod(nameof(Migration.Down), BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
    if (down is null) throw new InvalidOperationException($"{type.Name} does not override Down; rollback unsupported.");
}

Type guard

bool HasDownOverride(Type migrationType)
    => migrationType.GetMethod(nameof(Migration.Down),
        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) is not null;

Prevention

When it happens

Trigger: Running `dotnet ef database update <previous>` (or `Migrate(targetMigration)`) targeting a migration whose class only overrides `Up`. The migrator invokes `Down` to revert, hitting the base throw.

Common situations: Hand-written or generated migrations that only filled in `Up`; partial migration generation; attempting to roll back a migration that was never intended to be reverted.

Related errors


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