diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/PluginIdConstraint.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/PluginIdConstraint.php
new file mode 100644
index 0000000..c21fad2
--- /dev/null
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/PluginIdConstraint.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Validates a plugin ID.
+ *
+ * @Constraint(
+ *   id = "PluginId",
+ *   label = @Translation("Plugin ID", context = "Validation"),
+ * )
+ */
+class PluginIdConstraint extends Constraint {
+
+  public $message = 'The plugin ID %value does not exist.';
+  public $pluginManager = NULL;
+
+}
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/PluginIdConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/PluginIdConstraintValidator.php
new file mode 100644
index 0000000..df4a47f
--- /dev/null
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/PluginIdConstraintValidator.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
+
+use Drupal\Component\Plugin\PluginManagerInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * Validates a plugin ID exists.
+ */
+class PluginIdConstraintValidator extends ConstraintValidator {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($value, Constraint $constraint) {
+    $plugin_manager = \Drupal::service($constraint->pluginManager);
+    if (!($plugin_manager instanceof PluginManagerInterface)) {
+      throw new ConstraintDefinitionException('The given constraint contained an invalid plugin manager.');
+    }
+    if (!$plugin_manager->hasDefinition($value)) {
+      $this->context->addViolation($constraint->message, [
+        '%value' => $value,
+      ]);
+    }
+  }
+
+}
diff --git a/core/modules/config/tests/config_test/config/install/config_test.validation.yml b/core/modules/config/tests/config_test/config/install/config_test.validation.yml
index fa84ff3..87aa4ee 100644
--- a/core/modules/config/tests/config_test/config/install/config_test.validation.yml
+++ b/core/modules/config/tests/config_test/config/install/config_test.validation.yml
@@ -6,3 +6,4 @@ giraffe:
   hum1: hum1
   hum2: hum2
 uuid: '7C30C50E-641A-4E34-A7F1-46BCFB9BE5A3'
+plugin_id: 'valid_plugin_id'
diff --git a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml
index c25a577..f517f6a 100644
--- a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml
+++ b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml
@@ -195,3 +195,8 @@ config_test.validation:
             callback: [\Drupal\config_test\ConfigValidation, validateGiraffes]
     uuid:
       type: uuid
+    plugin_id:
+      type: string
+      constraints:
+        PluginId:
+          pluginManager: 'config_test.plugin_manager'
diff --git a/core/modules/config/tests/config_test/src/ConfigValidation.php b/core/modules/config/tests/config_test/src/ConfigValidation.php
index 9c69394..c0fbd2a 100644
--- a/core/modules/config/tests/config_test/src/ConfigValidation.php
+++ b/core/modules/config/tests/config_test/src/ConfigValidation.php
@@ -74,7 +74,7 @@ public static function validateGiraffes($string, ExecutionContextInterface $cont
    *   The validation execution context.
    */
   public static function validateMapping($mapping, ExecutionContextInterface $context) {
-    if ($diff = array_diff(array_keys($mapping), ['llama', 'cat', 'giraffe', 'uuid', '_core'])) {
+    if ($diff = array_diff(array_keys($mapping), ['llama', 'cat', 'giraffe', 'uuid', 'plugin_id', '_core'])) {
       $context->addViolation('Missing giraffe.');
     }
   }
diff --git a/core/modules/workflows/config/schema/workflows.schema.yml b/core/modules/workflows/config/schema/workflows.schema.yml
index 42a5d97..20e1c0c 100644
--- a/core/modules/workflows/config/schema/workflows.schema.yml
+++ b/core/modules/workflows/config/schema/workflows.schema.yml
@@ -11,6 +11,9 @@ workflows.workflow.*:
     type:
       type: string
       label: 'Workflow type'
+      constraints:
+        PluginId:
+          pluginManager: 'plugin.manager.workflows.type'
     type_settings:
       type: workflow.type_settings.[%parent.type]
 
diff --git a/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php b/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php
index 06881f2..bf33a06 100644
--- a/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php
+++ b/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\KernelTests\Config;
 
+use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\Core\Config\Schema\SequenceDataDefinition;
 use Drupal\Core\Config\Schema\TypedConfigInterface;
 use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
@@ -30,6 +31,10 @@ protected function setUp() {
     parent::setUp();
 
     $this->installConfig('config_test');
+
+    $plugin_manager = $this->prophesize(PluginManagerInterface::class);
+    $plugin_manager->hasDefinition('valid_plugin_id')->willReturn(TRUE);
+    $this->container->set('config_test.plugin_manager', $plugin_manager->reveal());
   }
 
   /**
@@ -75,7 +80,7 @@ public function testTypedDataAPI() {
     $typed_config_manager = \Drupal::service('config.typed');
     $typed_config = $typed_config_manager->createFromNameAndData('config_test.validation', \Drupal::configFactory()->get('config_test.validation')->get());
     $this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
-    $this->assertEquals(['llama', 'cat', 'giraffe', 'uuid', '_core'], array_keys($typed_config->getElements()));
+    $this->assertEquals(['llama', 'cat', 'giraffe', 'uuid', 'plugin_id', '_core'], array_keys($typed_config->getElements()));
 
     $config_test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
       'id' => 'asterix',
diff --git a/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php b/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php
index 8e17422..de6ffb7 100644
--- a/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\KernelTests\Core\Validation;
 
+use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\KernelTests\KernelTestBase;
 
 /**
@@ -21,25 +22,53 @@ class ConstraintsTest extends KernelTestBase {
    */
   protected function setUp() {
     parent::setUp();
-
     $this->installConfig('config_test');
+
+    $plugin_manager = $this->prophesize(PluginManagerInterface::class);
+    $plugin_manager->hasDefinition('valid_plugin_id')->willReturn(TRUE);
+    $plugin_manager->hasDefinition('invalid_plugin_id')->willReturn(FALSE);
+
+    $this->container->set('config_test.plugin_manager', $plugin_manager->reveal());
   }
 
   /**
-   * @see \Drupal\Core\Validation\Plugin\Validation\Constraint\UuidConstraint
+   * Test validation of various constraints.
+   *
+   * @dataProvider validationsDataProvider
    */
-  public function testUuid() {
+  public function testValidation($test_key, $value, $violatioin_count) {
     $typed_config_manager = \Drupal::service('config.typed');
-    /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
     $typed_config = $typed_config_manager->get('config_test.validation');
-    $typed_config->get('uuid')
-      ->setValue(\Drupal::service('uuid')->generate());
-
-    $this->assertCount(0, $typed_config->validate());
+    $typed_config->get($test_key)->setValue($value);
+    $this->assertCount($violatioin_count, $typed_config->validate());
+  }
 
-    $typed_config->get('uuid')
-      ->setValue(\Drupal::service('uuid')->generate() . '-invalid');
-    $this->assertCount(1, $typed_config->validate());
+  /**
+   * Data provider for ::testValidation.
+   */
+  public function validationsDataProvider() {
+    return [
+      'Valid UUID' => [
+        'uuid',
+        'd320a25d-7a65-4d27-ad02-2e5455493127',
+        0,
+      ],
+      'Invalid UUID' => [
+        'uuid',
+        'd320a25d-7a65-4d27-ad02-2e5455493127-invalid',
+        1,
+      ],
+      'Valid plugin ID' => [
+        'plugin_id',
+        'valid_plugin_id',
+        0,
+      ],
+      'Invalid plugin ID' => [
+        'plugin_id',
+        'invalid_plugin_id',
+        1,
+      ],
+    ];
   }
 
 }
