diff --git a/core/modules/migrate/src/MigrateExecutable.php b/core/modules/migrate/src/MigrateExecutable.php
index a370623..997f829 100644
--- a/core/modules/migrate/src/MigrateExecutable.php
+++ b/core/modules/migrate/src/MigrateExecutable.php
@@ -324,7 +324,7 @@ public function rollback() {
       $destination_key = $id_map->currentDestination();
       if ($destination_key) {
         $map_row = $id_map->getRowByDestination($destination_key);
-        if ($map_row['rollback_action'] == MigrateIdMapInterface::ROLLBACK_DELETE) {
+        if ($map_row && $map_row['rollback_action'] == MigrateIdMapInterface::ROLLBACK_DELETE) {
           $this->getEventDispatcher()
             ->dispatch(MigrateEvents::PRE_ROW_DELETE, new MigrateRowDeleteEvent($this->migration, $destination_key));
           $destination->rollback($destination_key);
diff --git a/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php
index a4911aa..1380697 100644
--- a/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php
+++ b/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php
@@ -106,6 +106,11 @@ protected function tearDown() {
    */
   protected function testMigrateUpgrade() {
     $connection_options = $this->sourceDatabase->getConnectionOptions();
+
+    foreach (array_keys(\Drupal::entityTypeManager()->getDefinitions()) as $entity_type) {
+      $original_counts[$entity_type] = count(\Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple());
+    }
+
     $this->drupalGet('/upgrade');
     $this->assertText('Upgrade a Drupal site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the upgrading handbook for more detailed information.');
 
@@ -143,6 +148,27 @@ protected function testMigrateUpgrade() {
       $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0;
       $this->assertEqual($expected_count, $real_count, "Found $real_count $entity_type entities, expected $expected_count.");
     }
+
+    // Test the rollback process.
+    $this->drupalGet('/upgrade');
+    $this->assertText('An upgrade has already been performed on this site.');
+
+    $edits = ['upgrade_option' => 2];
+    $this->drupalPostForm(NULL, $edits, t('Continue'));
+    $this->assertText('All previously imported content, as well as configuration such as field definitions, will be removed.');
+
+    $this->drupalPostForm(NULL, [], t('Perform rollback'));
+    $this->assertText('Rollback of the upgrade is complete - you may now start the upgrade process from scratch.');
+
+    // Have to reset all the statics after rollback to ensure entities are
+    // loadable.
+    $this->resetAll();
+
+    foreach (array_keys(\Drupal::entityTypeManager()->getDefinitions()) as $entity_type) {
+      $real_count = count(\Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple());
+      $expected_count = isset($original_counts[$entity_type]) ? $original_counts[$entity_type] : 0;
+      $this->assertEqual($expected_count, $real_count, "Found $real_count $entity_type entities, expected $expected_count.");
+    }
   }
 
   /**
