diff --git a/core/modules/ban/src/Plugin/migrate/destination/BlockedIp.php b/core/modules/ban/src/Plugin/migrate/destination/BlockedIp.php
index 7c570bb..19f6672 100644
--- a/core/modules/ban/src/Plugin/migrate/destination/BlockedIp.php
+++ b/core/modules/ban/src/Plugin/migrate/destination/BlockedIp.php
@@ -13,7 +13,8 @@
  * Destination for blocked IP addresses.
  *
  * @MigrateDestination(
- *   id = "blocked_ip"
+ *   id = "blocked_ip",
+ *   destination_module = "ban",
  * )
  */
 class BlockedIP extends DestinationBase implements ContainerFactoryPluginInterface {
diff --git a/core/modules/block/src/Plugin/migrate/destination/EntityBlock.php b/core/modules/block/src/Plugin/migrate/destination/EntityBlock.php
index 537b160..2a2a4fb 100644
--- a/core/modules/block/src/Plugin/migrate/destination/EntityBlock.php
+++ b/core/modules/block/src/Plugin/migrate/destination/EntityBlock.php
@@ -7,7 +7,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:block"
+ *   id = "entity:block",
+ *   destination_module = "block",
  * )
  */
 class EntityBlock extends EntityConfigBase {
diff --git a/core/modules/book/src/Plugin/migrate/destination/Book.php b/core/modules/book/src/Plugin/migrate/destination/Book.php
index 3659b34..cd5383e 100644
--- a/core/modules/book/src/Plugin/migrate/destination/Book.php
+++ b/core/modules/book/src/Plugin/migrate/destination/Book.php
@@ -9,7 +9,8 @@
 /**
  * @MigrateDestination(
  *   id = "book",
- *   provider = "book"
+ *   provider = "book",
+ *   destination_module = "book",
  * )
  */
 class Book extends EntityContentBase {
diff --git a/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php b/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php
index efce666..9e140ba 100644
--- a/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php
+++ b/core/modules/comment/src/Plugin/migrate/destination/EntityComment.php
@@ -13,7 +13,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:comment"
+ *   id = "entity:comment",
+ *   destination_module = "comment",
  * )
  */
 class EntityComment extends EntityContentBase {
diff --git a/core/modules/comment/src/Plugin/migrate/destination/EntityCommentType.php b/core/modules/comment/src/Plugin/migrate/destination/EntityCommentType.php
index 9bee87a..23a649e 100644
--- a/core/modules/comment/src/Plugin/migrate/destination/EntityCommentType.php
+++ b/core/modules/comment/src/Plugin/migrate/destination/EntityCommentType.php
@@ -7,7 +7,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:comment_type"
+ *   id = "entity:comment_type",
+ *   destination_module = "comment",
  * )
  */
 class EntityCommentType extends EntityConfigBase {
diff --git a/core/modules/field/migration_templates/d7_field.yml b/core/modules/field/migration_templates/d7_field.yml
index 1fa0069..85bfdf1 100644
--- a/core/modules/field/migration_templates/d7_field.yml
+++ b/core/modules/field/migration_templates/d7_field.yml
@@ -9,6 +9,7 @@ source:
   constants:
     status: true
     langcode: und
+  source_module: field
 process:
   entity_type: entity_type
   status: 'constants/status'
diff --git a/core/modules/file/src/Plugin/migrate/destination/EntityFile.php b/core/modules/file/src/Plugin/migrate/destination/EntityFile.php
index d0a1cca..16ea381 100644
--- a/core/modules/file/src/Plugin/migrate/destination/EntityFile.php
+++ b/core/modules/file/src/Plugin/migrate/destination/EntityFile.php
@@ -10,7 +10,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:file"
+ *   id = "entity:file",
+ *   destination_module = "file",
  * )
  */
 class EntityFile extends EntityContentBase {
diff --git a/core/modules/image/src/Plugin/migrate/destination/EntityImageStyle.php b/core/modules/image/src/Plugin/migrate/destination/EntityImageStyle.php
index 3fc1e7f..12daa7b 100644
--- a/core/modules/image/src/Plugin/migrate/destination/EntityImageStyle.php
+++ b/core/modules/image/src/Plugin/migrate/destination/EntityImageStyle.php
@@ -12,7 +12,8 @@
  * dependency on the d6_file migration to ensure it runs first.
  *
  * @MigrateDestination(
- *   id = "entity:image_style"
+ *   id = "entity:image_style",
+ *   destination_module = "image",
  * )
  */
 class EntityImageStyle extends EntityConfigBase {
diff --git a/core/modules/language/src/Plugin/migrate/destination/DefaultLangcode.php b/core/modules/language/src/Plugin/migrate/destination/DefaultLangcode.php
index 4d13e9a..40b232c 100644
--- a/core/modules/language/src/Plugin/migrate/destination/DefaultLangcode.php
+++ b/core/modules/language/src/Plugin/migrate/destination/DefaultLangcode.php
@@ -11,7 +11,8 @@
  * Provides a destination plugin for the default langcode config.
  *
  * @MigrateDestination(
- *   id = "default_langcode"
+ *   id = "default_langcode",
+ *   destination_module = "language",
  * )
  */
 class DefaultLangcode extends Config {
diff --git a/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php b/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php
index 0babe2f..641d46f 100644
--- a/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php
+++ b/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php
@@ -64,6 +64,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
         'class' => $class,
         'requirements_met' => 1,
         'provider' => $entity_info->getProvider(),
+        'destination_module' => $entity_info->getProvider(),
       ];
     }
     return $this->derivatives;
diff --git a/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php b/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php
index cee3b39..34632b3 100644
--- a/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php
+++ b/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php
@@ -62,6 +62,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
           'class' => 'Drupal\migrate\Plugin\migrate\destination\EntityRevision',
           'requirements_met' => 1,
           'provider' => $entity_info->getProvider(),
+          'destination_module' => $entity_info->getProvider(),
         ];
       }
     }
diff --git a/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php b/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php
index 090efd0..0350cec 100644
--- a/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php
+++ b/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\migrate\Plugin;
 
+use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -61,4 +62,17 @@ public function createInstance($plugin_id, array $configuration = [], MigrationI
     return parent::createInstance($plugin_id, $configuration, $migration);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function processDefinition(&$definition, $plugin_id) {
+    parent::processDefinition($definition, $plugin_id);
+
+    foreach (['destination_module'] as $required_property) {
+      if (empty($definition[$required_property])) {
+        throw new InvalidPluginDefinitionException($plugin_id, sprintf('The %s plugin should define the %s property.', $definition['class'], $required_property));
+      }
+    }
+  }
+
 }
diff --git a/core/modules/migrate/src/Plugin/MigratePluginManager.php b/core/modules/migrate/src/Plugin/MigratePluginManager.php
index b3645db..b46686f 100644
--- a/core/modules/migrate/src/Plugin/MigratePluginManager.php
+++ b/core/modules/migrate/src/Plugin/MigratePluginManager.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\migrate\Plugin;
 
+use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -62,4 +63,17 @@ public function createInstance($plugin_id, array $configuration = [], MigrationI
     return $plugin;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function processDefinition(&$definition, $plugin_id) {
+    parent::processDefinition($definition, $plugin_id);
+
+    foreach (['id'] as $required_property) {
+      if (empty($definition['id'])) {
+        throw new InvalidPluginDefinitionException($plugin_id, sprintf('The %s plugin should define the %s property.', $definition['class'], $required_property));
+      }
+    }
+  }
+
 }
diff --git a/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
index 965da5d..0da3886 100644
--- a/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
+++ b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\migrate\Plugin;
 
+use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\migrate\Plugin\Discovery\AnnotatedClassDiscoveryAutomatedProviders;
@@ -58,6 +59,8 @@ protected function getDiscovery() {
    * @todo This is a temporary solution to the fact that migration source
    *   plugins have more than one provider. This functionality will be moved to
    *   core in https://www.drupal.org/node/2786355.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
    */
   protected function findDefinitions() {
     $definitions = $this->getDiscovery()->getDefinitions();
@@ -70,4 +73,17 @@ protected function findDefinitions() {
     });
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function processDefinition(&$definition, $plugin_id) {
+    parent::processDefinition($definition, $plugin_id);
+
+    foreach (['source_module'] as $required_property) {
+      if (empty($definition[$required_property])) {
+        throw new InvalidPluginDefinitionException($plugin_id, sprintf('The %s plugin should define the %s property.', $definition['class'], $required_property));
+      }
+    }
+  }
+
 }
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/Config.php b/core/modules/migrate/src/Plugin/migrate/destination/Config.php
index 18d78a3..3d5b29c 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/Config.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/Config.php
@@ -66,7 +66,8 @@
  * @see \Drupal\migrate_drupal\Plugin\migrate\source\d6\i18nVariable
  *
  * @MigrateDestination(
- *   id = "config"
+ *   id = "config",
+ *   destination_module = "system",
  * )
  */
 class Config extends DestinationBase implements ContainerFactoryPluginInterface, DependentPluginInterface {
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityBaseFieldOverride.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityBaseFieldOverride.php
index 7523249..de20635 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityBaseFieldOverride.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityBaseFieldOverride.php
@@ -8,7 +8,8 @@
  * Provides entity base field override plugin.
  *
  * @MigrateDestination(
- *   id = "entity:base_field_override"
+ *   id = "entity:base_field_override",
+ *   destination_module = "system",
  * )
  */
 class EntityBaseFieldOverride extends EntityConfigBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php
index a431c49..d85baba 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php
@@ -6,7 +6,8 @@
  * Provides entity field instance plugin.
  *
  * @MigrateDestination(
- *   id = "entity:field_config"
+ *   id = "entity:field_config",
+ *   destination_module = "field",
  * )
  */
 class EntityFieldInstance extends EntityConfigBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
index 9b781a3..04608c0 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
@@ -6,7 +6,8 @@
  * Provides entity field storage configuration plugin.
  *
  * @MigrateDestination(
- *   id = "entity:field_storage_config"
+ *   id = "entity:field_storage_config",
+ *   destination_module = "field",
  * )
  */
 class EntityFieldStorageConfig extends EntityConfigBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php
index b0db476..e243552 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php
@@ -11,6 +11,7 @@
  *
  * @MigrateDestination(
  *   id = "entity_revision",
+ *   destination_module = "system",
  *   deriver = "Drupal\migrate\Plugin\Derivative\MigrateEntityRevision"
  * )
  */
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php
index b2c25a4..309b6b0 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php
@@ -25,7 +25,8 @@
  * "targetEntityType") to an "entity_view_mode" entity.
  *
  * @MigrateDestination(
- *   id = "entity:entity_view_mode"
+ *   id = "entity:entity_view_mode",
+ *   destination_module = "system",
  * )
  */
 class EntityViewMode extends EntityConfigBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php b/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php
index cfe47ea..7f0a41b 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php
@@ -10,7 +10,8 @@
  *
  * @MigrateDestination(
  *   id = "null",
- *   requirements_met = false
+ *   requirements_met = false,
+ *   destination_module = "null",
  * )
  */
 class NullDestination extends DestinationBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php
index 3b9a982..254b389 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php
@@ -45,7 +45,8 @@
  * "options" constant, for example the label will be hidden.
  *
  * @MigrateDestination(
- *   id = "component_entity_display"
+ *   id = "component_entity_display",
+ *   destination_module = "system",
  * )
  */
 class PerComponentEntityDisplay extends ComponentEntityDisplayBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php
index bd837f0..f8e10dd 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php
@@ -38,7 +38,8 @@
  * entity type with options defined by the "options" constant.
  *
  * @MigrateDestination(
- *   id = "component_entity_form_display"
+ *   id = "component_entity_form_display",
+ *   destination_module = "system",
  * )
  */
 class PerComponentEntityFormDisplay extends ComponentEntityDisplayBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php b/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php
index 8cee6dd..2be0b5e 100644
--- a/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php
+++ b/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php
@@ -38,7 +38,8 @@
  * @see \Drupal\migrate\Plugin\MigrateSourceInterface
  *
  * @MigrateSource(
- *   id = "embedded_data"
+ *   id = "embedded_data",
+ *   source_module = "migrate"
  * )
  */
 class EmbeddedDataSource extends SourcePluginBase {
diff --git a/core/modules/migrate/src/Plugin/migrate/source/EmptySource.php b/core/modules/migrate/src/Plugin/migrate/source/EmptySource.php
index 2391b0a..4ae99e8 100644
--- a/core/modules/migrate/src/Plugin/migrate/source/EmptySource.php
+++ b/core/modules/migrate/src/Plugin/migrate/source/EmptySource.php
@@ -8,7 +8,8 @@
  * This is generally useful when needing to create a field using a migration..
  *
  * @MigrateSource(
- *   id = "empty"
+ *   id = "empty",
+ *   source_module = "migrate"
  * )
  */
 class EmptySource extends SourcePluginBase {
diff --git a/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php b/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php
index 415d000..ad8a555 100644
--- a/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php
+++ b/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php
@@ -9,7 +9,8 @@
 /**
  * @MigrateDestination(
  *   id = "dummy",
- *   requirements_met = true
+ *   requirements_met = true,
+ *   destination_module = "migrate_events_test",
  * )
  */
 class DummyDestination extends DestinationBase {
diff --git a/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php b/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php
index 601bbd9..50b70cd 100644
--- a/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php
+++ b/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php
@@ -8,7 +8,8 @@
  * Source plugin for migration high water tests.
  *
  * @MigrateSource(
- *   id = "high_water_test"
+ *   id = "high_water_test",
+ *   source_module = "migrate_high_water_test",
  * )
  */
 class HighWaterTest extends SqlBase {
diff --git a/core/modules/migrate/tests/modules/migrate_query_batch_test/src/Plugin/migrate/source/QueryBatchTest.php b/core/modules/migrate/tests/modules/migrate_query_batch_test/src/Plugin/migrate/source/QueryBatchTest.php
index cc00c0d..c1dd22d 100644
--- a/core/modules/migrate/tests/modules/migrate_query_batch_test/src/Plugin/migrate/source/QueryBatchTest.php
+++ b/core/modules/migrate/tests/modules/migrate_query_batch_test/src/Plugin/migrate/source/QueryBatchTest.php
@@ -8,7 +8,8 @@
  * Source plugin for migration high water tests.
  *
  * @MigrateSource(
- *   id = "query_batch_test"
+ *   id = "query_batch_test",
+ *   source_module = "migrate_query_batch_test",
  * )
  */
 class QueryBatchTest extends SqlBase {
diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php
index 8e16699..94cd2a2 100644
--- a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php
+++ b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\migrate\Kernel\Plugin;
 
+use Drupal\Component\Discovery\DiscoveryException;
+use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
@@ -16,49 +18,58 @@ class MigrationProvidersExistTest extends MigrateDrupalTestBase {
   use FileSystemModuleDiscoveryDataProviderTrait;
 
   /**
-   * {@inheritdoc}
+   * Tests missing source module.
    */
-  public static $modules = ['migration_provider_test'];
+  public function testSourceProvider() {
+    $this->enableAllModules();
+    $this->enableModules(['migration_provider_test']);
+    $source_plugin_manager = $this->container->get('plugin.manager.migrate.source');
+    $this->setExpectedException(InvalidPluginDefinitionException::class, 'The Drupal\migration_provider_test\Plugin\migrate\source\NoSourceModule plugin should define the source_module property.');
+    $source_plugin_manager->getDefinitions();
+  }
+
+  /**
+   * Tests missing destination module.
+   */
+  public function testDestinationProvider() {
+    $this->enableAllModules();
+    $this->enableModules(['migration_provider_test']);
+    $destination_plugin_manager = $this->container->get('plugin.manager.migrate.destination');
+    $this->setExpectedException(InvalidPluginDefinitionException::class, 'The Drupal\migration_provider_test\Plugin\migrate\destination\NoDestinationModule plugin should define the destination_module property.');
+    $destination_plugin_manager->getDefinitions();
+  }
 
   /**
    * Tests that modules exist for all source and destination plugins.
    */
   public function testProvidersExist() {
-    // Install all available modules.
-    $module_handler = $this->container->get('module_handler');
-    $modules = $this->coreModuleListDataProvider();
-    $modules_enabled = $module_handler->getModuleList();
-    $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
-    $this->enableModules($modules_to_enable);
-
+    $this->enableAllModules();
+    // Get all the migrations
     /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
     $plugin_manager = $this->container->get('plugin.manager.migration');
-    // Get all the migrations
     $migrations = $plugin_manager->createInstances(array_keys($plugin_manager->getDefinitions()));
-    // Ensure the test module was enabled.
-    $this->assertTrue(array_key_exists('migration_provider_test', $migrations));
-    $this->assertTrue(array_key_exists('migration_provider_no_annotation', $migrations));
     /** @var \Drupal\migrate\Plugin\Migration $migration */
     foreach ($migrations as $migration) {
-      $source_module = $migration->getSourcePlugin()->getSourceModule();
       $destination_module = $migration->getDestinationPlugin()->getDestinationModule();
       $migration_id = $migration->getPluginId();
-      if ($migration_id == 'migration_provider_test') {
-        $this->assertFalse($source_module, new FormattableMarkup('Source module not found for @migration_id.', ['@migration_id' => $migration_id]));
-        $this->assertFalse($destination_module, new FormattableMarkup('Destination module not found for @migration_id.', ['@migration_id' => $migration_id]));
-      }
-      elseif ($migration_id == 'migration_provider_no_annotation') {
-        $this->assertFalse($source_module, new FormattableMarkup('Source module not found for @migration_id.', ['@migration_id' => $migration_id]));
-        $this->assertTrue($destination_module, new FormattableMarkup('Destination module found for @migration_id.', ['@migration_id' => $migration_id]));
-      }
-      else {
-        $this->assertTrue($source_module, new FormattableMarkup('Source module found for @migration_id.', ['@migration_id' => $migration_id]));
-        $this->assertTrue($destination_module, new FormattableMarkup('Destination module found for @migration_id.', ['@migration_id' => $migration_id]));
-      }
       // Destination module can't be migrate or migrate_drupal or migrate_drupal_ui
       $invalid_destinations = ['migrate', 'migrate_drupal', 'migrate_drupal_ui'];
       $this->assertNotContains($destination_module, $invalid_destinations, new FormattableMarkup('Invalid destination for @migration_id.', ['@migration_id' => $migration_id]));
     }
   }
 
+  /**
+   * Enable all available modules.
+   *
+   * @throws \Exception
+   */
+  protected function enableAllModules() {
+    // Install all available modules.
+    $module_handler = $this->container->get('module_handler');
+    $modules = $this->coreModuleListDataProvider();
+    $modules_enabled = $module_handler->getModuleList();
+    $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
+    $this->enableModules($modules_to_enable);
+  }
+
 }
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
index c5e631a..a076e24 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php
@@ -14,7 +14,8 @@
  * Deprecated. Destination with Drupal specific config dependencies.
  *
  * @MigrateDestination(
- *   id = "md_entity:field_storage_config"
+ *   id = "md_entity:field_storage_config",
+ *   destination_module = "field",
  * )
  *
  * @deprecated in Drupal 8.2.x and will be removed in Drupal 9.0.x. Use
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php
index 6792e5e..57db7b4 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php
@@ -15,7 +15,8 @@
  * Source returning an empty row with Drupal specific config dependencies.
  *
  * @MigrateSource(
- *   id = "md_empty"
+ *   id = "md_empty",
+ *   source_module = "system"
  * )
  */
 class EmptySource extends BaseEmptySource implements ContainerFactoryPluginInterface, DependentPluginInterface {
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php
index 410acec..e8b1ee0 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php
@@ -13,7 +13,8 @@
  * example for any normal source class returning multiple rows.
  *
  * @MigrateSource(
- *   id = "variable"
+ *   id = "variable",
+ *   source_module = "system"
  * )
  */
 class Variable extends DrupalSqlBase {
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php
index 61da5eb..02b3245 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php
@@ -11,7 +11,8 @@
  * variable.
  *
  * @MigrateSource(
- *   id = "variable_multirow"
+ *   id = "variable_multirow",
+ *   source_module = "system"
  * )
  */
 class VariableMultiRow extends DrupalSqlBase {
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/VariableTranslation.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/VariableTranslation.php
index 566a840..3dd5a76 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/VariableTranslation.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/VariableTranslation.php
@@ -11,7 +11,8 @@
  * Drupal i18n_variable source from database.
  *
  * @MigrateSource(
- *   id = "variable_translation"
+ *   id = "variable_translation",
+ *   source_module = "system"
  * )
  */
 class VariableTranslation extends DrupalSqlBase {
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php
index dd8d0f0..8e6c391 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php
@@ -8,7 +8,8 @@
  * Drupal i18n_variable source from database.
  *
  * @MigrateSource(
- *   id = "i18n_variable"
+ *   id = "i18n_variable",
+ *   source_module = "system"
  * )
  *
  * @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php
index 8d83387..5ae76b9 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php
@@ -9,7 +9,8 @@
  * Drupal config source from database.
  *
  * @MigrateSource(
- *   id = "d8_config"
+ *   id = "d8_config",
+ *   source_module = "system"
  * )
  */
 class Config extends DrupalSqlBase {
diff --git a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_no_annotation.yml b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_no_annotation.yml
index bdc9066..09d0b6e 100644
--- a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_no_annotation.yml
+++ b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_no_annotation.yml
@@ -9,5 +9,4 @@ source:
 process:
   message: site_offline_message
 destination:
-  plugin: config
-  config_name: test.settings
+  plugin: no_destination_module
diff --git a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_test.yml b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_test.yml
deleted file mode 100644
index d3afc66..0000000
--- a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_test.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-id: migration_provider_test
-label: Missing source and destination provider
-migration_tags:
-  - Drupal 6
-  - Drupal 7
-source:
-  plugin: variable
-  variables:
-    - site_offline_message
-# Do not add a provider for the test.
-process:
-  message: site_offline_message
-destination:
-  plugin: config
-# An empty config_name will not have a destination provider.
-  config_name:
\ No newline at end of file
diff --git a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/src/Plugin/migrate/destination/NoDestinationModule.php b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/src/Plugin/migrate/destination/NoDestinationModule.php
new file mode 100644
index 0000000..1ef4fd5
--- /dev/null
+++ b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/src/Plugin/migrate/destination/NoDestinationModule.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\migration_provider_test\Plugin\migrate\destination;
+
+use Drupal\migrate\Annotation\MigrateDestination;
+use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
+
+/**
+ * A test destination plugin without a destination_module.
+ *
+ * @MigrateDestination(
+ *   id = "no_destination_module",
+ * )
+ */
+class NoDestinationModule extends EntityContentBase {}
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
index 5d2c605..fd702b1 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
@@ -147,11 +147,9 @@ public function testMigrateUpgrade() {
 
     $this->drupalPostForm(NULL, $edits, t('Review upgrade'));
     $this->assertResponse(200);
-    $this->assertText('Are you sure?');
     // Ensure we get errors about missing modules.
-    $this->assertSession()->pageTextContains(t('Source module not found for migration_provider_no_annotation.'));
-    $this->assertSession()->pageTextContains(t('Source module not found for migration_provider_test.'));
-    $this->assertSession()->pageTextContains(t('Destination module not found for migration_provider_test'));
+    $this->assertSession()->pageTextContains(t('Resolve the issue below to continue the upgrade'));
+    $this->assertSession()->pageTextContains(t('NoSourceModule plugin should define the source_module property.'));
 
     // Uninstall the module causing the missing module error messages.
     $this->container->get('module_installer')->uninstall(['migration_provider_test'], TRUE);
diff --git a/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php b/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php
index c26f3b9..c836232 100644
--- a/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php
+++ b/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php
@@ -7,7 +7,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:node_type"
+ *   id = "entity:node_type",
+ *   destination_module = "node",
  * )
  */
 class EntityNodeType extends EntityConfigBase {
diff --git a/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php b/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php
index 385ee4b..953b739 100644
--- a/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php
+++ b/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php
@@ -11,7 +11,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "url_alias"
+ *   id = "url_alias",
+ *   destination_module = "path",
  * )
  */
 class UrlAlias extends DestinationBase implements ContainerFactoryPluginInterface {
diff --git a/core/modules/search/src/Plugin/migrate/destination/EntitySearchPage.php b/core/modules/search/src/Plugin/migrate/destination/EntitySearchPage.php
index ddd8da7..03f109a 100644
--- a/core/modules/search/src/Plugin/migrate/destination/EntitySearchPage.php
+++ b/core/modules/search/src/Plugin/migrate/destination/EntitySearchPage.php
@@ -8,7 +8,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:search_page"
+ *   id = "entity:search_page",
+ *   destination_module = "search",
  * )
  */
 class EntitySearchPage extends EntityConfigBase {
diff --git a/core/modules/shortcut/src/Plugin/migrate/destination/EntityShortcutSet.php b/core/modules/shortcut/src/Plugin/migrate/destination/EntityShortcutSet.php
index fddf08a..4c794ba 100644
--- a/core/modules/shortcut/src/Plugin/migrate/destination/EntityShortcutSet.php
+++ b/core/modules/shortcut/src/Plugin/migrate/destination/EntityShortcutSet.php
@@ -7,7 +7,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:shortcut_set"
+ *   id = "entity:shortcut_set",
+ *   destination_module = "shortcut",
  * )
  */
 class EntityShortcutSet extends EntityConfigBase {
diff --git a/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php b/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php
index 0cb843b..0a4e19b 100644
--- a/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php
+++ b/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php
@@ -12,7 +12,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "shortcut_set_users"
+ *   id = "shortcut_set_users",
+ *   destination_module = "shortcut",
  * )
  */
 class ShortcutSetUsers extends DestinationBase implements ContainerFactoryPluginInterface {
diff --git a/core/modules/system/src/Plugin/migrate/destination/EntityDateFormat.php b/core/modules/system/src/Plugin/migrate/destination/EntityDateFormat.php
index 42ba166..acdffae 100644
--- a/core/modules/system/src/Plugin/migrate/destination/EntityDateFormat.php
+++ b/core/modules/system/src/Plugin/migrate/destination/EntityDateFormat.php
@@ -7,7 +7,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:date_format"
+ *   id = "entity:date_format",
+ *   destination_module = "system",
  * )
  */
 class EntityDateFormat extends EntityConfigBase {
diff --git a/core/modules/system/src/Plugin/migrate/destination/d7/ThemeSettings.php b/core/modules/system/src/Plugin/migrate/destination/d7/ThemeSettings.php
index 55ac721..b7f935c 100644
--- a/core/modules/system/src/Plugin/migrate/destination/d7/ThemeSettings.php
+++ b/core/modules/system/src/Plugin/migrate/destination/d7/ThemeSettings.php
@@ -13,7 +13,8 @@
  * Persist theme settings to the config system.
  *
  * @MigrateDestination(
- *   id = "d7_theme_settings"
+ *   id = "d7_theme_settings",
+ *   destination_module = "system",
  * )
  */
 class ThemeSettings extends DestinationBase implements ContainerFactoryPluginInterface {
diff --git a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
index 7c2c81a..f5fb9ea 100644
--- a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
+++ b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
@@ -16,7 +16,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "entity:user"
+ *   id = "entity:user",
+ *   destination_module = "user",
  * )
  */
 class EntityUser extends EntityContentBase {
diff --git a/core/modules/user/src/Plugin/migrate/destination/UserData.php b/core/modules/user/src/Plugin/migrate/destination/UserData.php
index 7c48f93..8843deb 100644
--- a/core/modules/user/src/Plugin/migrate/destination/UserData.php
+++ b/core/modules/user/src/Plugin/migrate/destination/UserData.php
@@ -11,7 +11,8 @@
 
 /**
  * @MigrateDestination(
- *   id = "user_data"
+ *   id = "user_data",
+ *   destination_module = "user",
  * )
  */
 class UserData extends DestinationBase implements ContainerFactoryPluginInterface {
