diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
index e245874..62f3dd3 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Component\Plugin\Discovery;
 
+use Drupal\Component\Plugin\Exception\DerivativeNotFoundException;
+
 /**
  * Base class providing the tools for a plugin discovery to be derivative aware.
  *
@@ -33,7 +35,7 @@ public function __construct(DiscoveryInterface $decorated) {
   /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
 
     list($base_plugin_id, $derivative_id) = $this->decodePluginId($plugin_id);
 
@@ -42,6 +44,15 @@ public function getDefinition($plugin_id) {
       $derivative_fetcher = $this->getDerivativeFetcher($base_plugin_id, $plugin_definition);
       if ($derivative_fetcher) {
         $plugin_definition = $derivative_fetcher->getDerivativeDefinition($derivative_id, $plugin_definition);
+        if (!isset($plugin_definition)) {
+          if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+            // @todo will this handle nested derivatives gracefuly?
+            throw new DerivativeNotFoundException(sprintf('Derivative plugin "%s", derived from base plugin "%s", could not be found.', $base_plugin_id, $derivative_id));
+          }
+          else {
+            return;
+          }
+        }
       }
     }
 
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
index aaf4743..5659b60 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php
@@ -7,22 +7,32 @@
 
 namespace Drupal\Component\Plugin\Discovery;
 
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+
 /**
  * An interface defining the minimum requirements of building a plugin
  * discovery component.
  */
 interface DiscoveryInterface {
 
+  const EXCEPTION_ON_INVALID_ID = 1;
+  const NULL_ON_INVALID_ID = 2;
+
   /**
    * Gets a specific plugin definition.
    *
    * @param string $plugin_id
    *   A plugin id.
    *
-   * @return array|null
-   *   A plugin definition, or NULL if no definition was found for $plugin_id.
+   * @param bool $exception
+   *   Whether to throw an exception if the specified plugin could not be found.
+   *
+   * @return array
+   *   A plugin definition. An exception is thrown if no plugin could be found.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
    */
-  public function getDefinition($plugin_id);
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID);
 
   /**
    * Gets the definition of all plugins for this type.
diff --git a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
index de74fb5..080854f 100644
--- a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
+++ b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscovery.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Component\Plugin\Discovery;
 
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+
 /**
  * A discovery mechanism that allows plugin definitions to be manually
  * registered rather than actively discovered.
@@ -23,8 +25,13 @@ class StaticDiscovery implements DiscoveryInterface {
   /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
    */
-  public function getDefinition($base_plugin_id) {
-    return isset($this->definitions[$base_plugin_id]) ? $this->definitions[$base_plugin_id] : NULL;
+  public function getDefinition($base_plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
+    if (isset($this->definitions[$base_plugin_id])) {
+      return $this->definitions[$base_plugin_id];
+    }
+    else if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+      throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $base_plugin_id));;
+    }
   }
 
   /**
diff --git a/core/lib/Drupal/Component/Plugin/Exception/DerivativeNotFoundException.php b/core/lib/Drupal/Component/Plugin/Exception/DerivativeNotFoundException.php
new file mode 100644
index 0000000..0b0b3d1
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Exception/DerivativeNotFoundException.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @file
+ * Definition of Drupal\Component\Plugin\Exception\DerivativeNotFoundException.
+ */
+
+namespace Drupal\Component\Plugin\Exception;
+
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+
+/**
+ * Exception thrown to indicate that Discovery failed to find a specific
+ * derivative of a specific plugin.
+ */
+class DerivativeNotFoundException extends PluginNotFoundException { }
diff --git a/core/lib/Drupal/Component/Plugin/Exception/PluginNotFoundException.php b/core/lib/Drupal/Component/Plugin/Exception/PluginNotFoundException.php
new file mode 100644
index 0000000..6837ef3
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Exception/PluginNotFoundException.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * @file
+ * Definition of Drupal\Component\Plugin\Exception\PluginNotFoundException.
+ */
+
+namespace Drupal\Component\Plugin\Exception;
+
+use Drupal\Component\Plugin\Exception\PluginException;
+
+/**
+ * Exception thrown to indicate that Discovery failed to find a specific plugin.
+ */
+class PluginNotFoundException extends PluginException { }
diff --git a/core/lib/Drupal/Component/Plugin/PluginManagerBase.php b/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
index c337f9f..85af54c 100644
--- a/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
+++ b/core/lib/Drupal/Component/Plugin/PluginManagerBase.php
@@ -9,11 +9,12 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 
 /**
  * Base class for plugin managers.
  */
-abstract class PluginManagerBase implements PluginManagerInterface, CachedDiscoveryInterface {
+abstract class PluginManagerBase implements PluginManagerInterface {
 
   /**
    * The object that discovers plugins managed by this manager.
@@ -48,12 +49,22 @@
   /**
    * Implements Drupal\Component\Plugin\PluginManagerInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
-    $definition = $this->discovery->getDefinition($plugin_id);
-    if (isset($definition)) {
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
+    try {
+      $definition = $this->discovery->getDefinition($plugin_id, $invalid_behavior);
+    }
+    catch (PluginNotFoundException $e) {
+      $refl = new \ReflectionClass($e);
+      // Ensure we reproduce the exact same exception type, even if a child class.
+      // @todo this is horrible. can we make this better?
+      throw $refl->newInstance(sprintf('Plugin manager "%s" was unable to find plugin with id "%s".', get_class($this), $plugin_id), E_RECOVERABLE_ERROR, $e);
+      // throw new PluginNotFoundException(sprintf('Plugin manager "%s" was unable to find plugin with id "%s".', get_class($this), $plugin_id), E_RECOVERABLE_ERROR, $e);
+    }
+
+    if (!is_null($definition)) {
       $this->processDefinition($definition, $plugin_id);
+      return $definition;
     }
-    return $definition;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 6c8e48b..b8426c9 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\Core\Plugin\Discovery\InfoHookDecorator;
@@ -239,9 +240,14 @@ public function __construct() {
   /**
    * Overrides Drupal\Component\Plugin\PluginManagerBase::getDefinition().
    */
-  public function getDefinition($plugin_id) {
+  public function getDefinition($plugin_id, $exception = TRUE) {
     $definitions = $this->getDefinitions();
-    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    else if ($exception) {
+      throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $plugin_id));;
+    }
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
index 8bcee3f..fab047f 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AlterDecorator.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 
 /**
  * Enables altering of discovered plugin definitions.
@@ -45,9 +46,14 @@ public function __construct(DiscoveryInterface $decorated, $hook) {
   /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
     $definitions = $this->getDefinitions();
-    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    else if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+      throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $plugin_id));;
+    }
   }
 
 
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
index bd89a92..74380f5 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -10,6 +10,7 @@
 use DirectoryIterator;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Component\Reflection\MockFileFinder;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Core\Annotation\Plugin;
 use Doctrine\Common\Annotations\AnnotationReader;
 use Doctrine\Common\Annotations\AnnotationRegistry;
@@ -31,9 +32,14 @@ function __construct($owner, $type) {
   /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
-    $plugins = $this->getDefinitions();
-    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : NULL;
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
+    $definitions = $this->getDefinitions();
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    else if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+      throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $plugin_id));;
+    }
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
index 67d6cab..b482567 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 
 /**
  * Enables static and persistent caching of discovered plugin definitions.
@@ -64,9 +65,14 @@ public function __construct(DiscoveryInterface $decorated, $cache_key, $cache_bi
   /**
    * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
     $definitions = $this->getDefinitions();
-    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    else if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+      throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $plugin_id));;
+    }
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
index 0c77a2f..b7c6d3c 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 
 /**
  * Provides a hook-based plugin discovery class.
@@ -35,9 +36,14 @@ function __construct($hook) {
   /**
    * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
-    $plugins = $this->getDefinitions();
-    return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : NULL;
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
+    $definitions = $this->getDefinitions();
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    else if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+      throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $plugin_id));;
+    }
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php
index 7ba8913..04b4418 100644
--- a/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php
+++ b/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Plugin\Discovery;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 
 /**
  * Allows info hook implementations to enhance discovered plugin definitions.
@@ -44,9 +45,14 @@ public function __construct(DiscoveryInterface $decorated, $hook) {
   /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
     $definitions = $this->getDefinitions();
-    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    else if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+        throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $plugin_id));;
+    }
   }
 
   /**
diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc
index b659c97..60eb3ba 100644
--- a/core/modules/field/field.info.inc
+++ b/core/modules/field/field.info.inc
@@ -243,7 +243,7 @@ function field_info_widget_types($widget_type = NULL) {
  */
 function field_info_formatter_types($formatter_type = NULL) {
   if ($formatter_type) {
-    return drupal_container()->get('plugin.manager.field.formatter')->getDefinition($formatter_type);
+    return drupal_container()->get('plugin.manager.field.formatter')->getDefinition($formatter_type, FALSE);
   }
   else {
     return drupal_container()->get('plugin.manager.field.formatter')->getDefinitions();
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
index 7f17d34..ee81484 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
@@ -8,6 +8,7 @@
 namespace Drupal\field\Plugin\Type\Formatter;
 
 use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 use Drupal\field\Plugin\Type\Formatter\FormatterLegacyDiscoveryDecorator;
@@ -45,7 +46,7 @@ public function getInstance(array $options) {
     $instance = $options['instance'];
     $type = $options['type'];
 
-    $definition = $this->getDefinition($type);
+    $definition = $this->getDefinition($type, DiscoveryInterface::NULL_ON_INVALID_ID);
     $field = field_info_field($instance['field_name']);
 
     // Switch back to default formatter if either:
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/LegacyDiscoveryDecorator.php b/core/modules/field/lib/Drupal/field/Plugin/Type/LegacyDiscoveryDecorator.php
index 43aad82..dbedd66 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/LegacyDiscoveryDecorator.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/LegacyDiscoveryDecorator.php
@@ -8,6 +8,7 @@
 namespace Drupal\field\Plugin\Type;
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Core\Plugin\Discovery\HookDiscovery;
 
 /**
@@ -46,9 +47,14 @@ public function __construct(DiscoveryInterface $decorated) {
   /**
    * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition().
    */
-  public function getDefinition($plugin_id) {
+  public function getDefinition($plugin_id, $invalid_behavior = self::EXCEPTION_ON_INVALID_ID) {
     $definitions = $this->getDefinitions();
-    return isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL;
+    if (isset($definitions[$plugin_id])) {
+      return $definitions[$plugin_id];
+    }
+    else if ($invalid_behavior === self::EXCEPTION_ON_INVALID_ID) {
+      throw new PluginNotFoundException(sprintf('The plugin (%s) could not be found.', $plugin_id));;
+    }
   }
 
   /**
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
index c5407bd..26c10b6 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php
@@ -8,6 +8,7 @@
 namespace Drupal\field\Plugin\Type\Widget;
 
 use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Core\Plugin\Discovery\CacheDecorator;
 use Drupal\Core\Plugin\Discovery\AlterDecorator;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
@@ -46,7 +47,7 @@ public function getInstance(array $options) {
     $instance = $options['instance'];
     $type = $options['type'];
 
-    $definition = $this->getDefinition($type);
+    $definition = $this->getDefinition($type, DiscoveryInterface::NULL_ON_INVALID_ID);
     $field = field_info_field($instance['field_name']);
 
     // Switch back to default widget if either:
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php
index 327e46e..eb5098c 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php
@@ -122,7 +122,7 @@ public function testClearCachedDefinitions() {
     $this->discovery->setDefinition('banana', $this->expectedDefinitions['banana']);
 
     // Check that the new definition is not found.
-    $definition = $this->discovery->getDefinition('banana');
+    $definition = $this->discovery->getDefinition('banana', FALSE);
     $this->assertNull($definition, 'Newly added definition is not found.');
 
     // Clear cached definitions, and check that the new definition is found.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php
index 226b28d..ff5f6c0 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/DerivativeTest.php
@@ -6,6 +6,8 @@
  */
 
 namespace Drupal\system\Tests\Plugin;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\Component\Plugin\Exception\DerivativeNotFoundException;
 
 /**
  * Tests that derivative plugins are correctly discovered.
@@ -32,11 +34,32 @@ function testDerivativeDecorator() {
       $this->assertIdentical($this->mockBlockManager->getDefinition($id), $definition);
     }
 
-    // Ensure that NULL is returned as the definition of a non-existing base
-    // plugin, a non-existing derivative plugin, or a base plugin that may not
-    // be used without deriving.
-    $this->assertIdentical($this->mockBlockManager->getDefinition('non_existing'), NULL, 'NULL returned as the definition of a non-existing base plugin.');
-    $this->assertIdentical($this->mockBlockManager->getDefinition('menu:non_existing'), NULL, 'NULL returned as the definition of a non-existing derivative plugin.');
-    $this->assertIdentical($this->mockBlockManager->getDefinition('menu'), NULL, 'NULL returned as the definition of a base plugin that may not be used without deriving.');
+    // Ensure that the correct exceptions are thrown when non-existent plugins
+    // and derivatives are requested.
+    try {
+      $this->mockBlockManager->getDefinition('non_existing');
+      $this->fail('mockBlockManager->getDefinition() should throw a PluginNotFoundException when looking for a nonexistent plugin.');
+    }
+    catch (\Exception $e) {
+      $this->assertTrue($e instanceof PluginNotFoundException, 'PluginNotFoundException thrown when attempting to retrieve definition for nonexistent base plugin.');
+    }
+
+    try {
+      $this->mockBlockManager->getDefinition('menu:non_existing');
+      $this->fail('mockBlockManager->getDefinition() should throw a DerivativeNotFoundException when looking for a nonexistent derived plugin.');
+    }
+    catch (\Exception $e) {
+      $this->assertTrue($e instanceof DerivativeNotFoundException, 'DerivativeNotFoundException thrown when attempting to retrieve definition for nonexistent derived plugin.');
+    }
+
+    try {
+      $this->mockBlockManager->getDefinition('menu');
+      $this->fail('mockBlockManager->getDefinition() should throw a PluginNotFoundException when looking for a plugin that can only be used as a source for derived plugins.');
+    }
+    catch (\Exception $e) {
+      $this->assertTrue($e instanceof PluginNotFoundException, 'PluginNotFoundException thrown when attempting to retrieve definition for a plugin that can only be used as a source for derived plugins.');
+    }
+
+
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php
index e95d238..25f6574 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/DiscoveryTestBase.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\system\Tests\Plugin\Discovery;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 
 use Drupal\simpletest\UnitTestBase;
 
@@ -55,8 +56,14 @@ function testDiscoveryInterface() {
     // Ensure that an empty array is returned if no plugin definitions are found.
     $this->assertIdentical($this->emptyDiscovery->getDefinitions(), array(), 'array() returned if no plugin definitions are found.');
 
-    // Ensure that NULL is returned as the definition of a non-existing plugin.
-    $this->assertIdentical($this->emptyDiscovery->getDefinition('non_existing'), NULL, 'NULL returned as the definition of a non-existing plugin.');
+    // Ensure that an exception is thrown when a non-existing plugin is sought.
+    try {
+      $this->emptyDiscovery->getDefinition('non_existing');
+      $this->fail('PluginNotFoundException should be thrown when Discovery looks for a nonexistent plugin.');
+    }
+    catch (\Exception $e) {
+      $this->assertTrue($e instanceof PluginNotFoundException, 'PluginNotFoundException thrown when Discovery looks for a nonexistent plugin.');
+    }
   }
 }
 
