diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 26a75f6..1bcec37 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -208,10 +208,23 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) {
  *   The filename of the requested item or NULL if the item is not found.
  */
 function drupal_get_filename($type, $name, $filename = NULL) {
+  // Return NULL right away if $type or $name is empty.
+  if (empty($type) || empty($name)) {
+    return NULL;
+  }
+
   // The location of files will not change during the request, so do not use
   // drupal_static().
   static $files = array();
 
+  // We use drupal static for the missing records so we can test it.
+  // Drupal static fast pattern is used as this function may be called often.
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['missing'] = &drupal_static(__FUNCTION__ . ':missing');
+  }
+  $missing = &$drupal_static_fast['missing'];
+
   // Type 'core' only exists to simplify application-level logic; it always maps
   // to the /core directory, whereas $name is ignored. It is only requested via
   // drupal_get_path(). /core/core.info.yml does not exist, but is required
@@ -251,13 +264,24 @@ function drupal_get_filename($type, $name, $filename = NULL) {
     }
     // If still unknown, perform a filesystem scan.
     if (!isset($files[$type][$name])) {
-      $listing = new ExtensionDiscovery(DRUPAL_ROOT);
-      // Prevent an infinite recursion by this legacy function.
-      if ($original_type == 'profile') {
-        $listing->setProfileDirectories(array());
+      if (!isset($missing)) {
+        $missing = array();
+        if (\Drupal::hasService('cache.bootstrap')) {
+          $cache = \Drupal::cache('bootstrap')->get('drupal_get_filename:missing');
+          if ($cache && $cache->data) {
+            $missing = $cache->data;
+          }
+        }
       }
-      foreach ($listing->scan($original_type) as $extension_name => $file) {
-        $files[$type][$extension_name] = $file->getPathname();
+      if (!isset($missing[$type][$name])) {
+        $listing = new ExtensionDiscovery(DRUPAL_ROOT);
+        // Prevent an infinite recursion by this legacy function.
+        if ($original_type == 'profile') {
+          $listing->setProfileDirectories(array());
+        }
+        foreach ($listing->scan($original_type) as $extension_name => $file) {
+          $files[$type][$extension_name] = $file->getPathname();
+        }
       }
     }
   }
@@ -265,6 +289,16 @@ function drupal_get_filename($type, $name, $filename = NULL) {
   if (isset($files[$type][$name])) {
     return $files[$type][$name];
   }
+  elseif (!isset($missing[$type][$name])) {
+    // Add the missing file to a temporary cache and throw an alert. This cache
+    // will be cleared on cron runs as well as when visiting the module and
+    // theme list pages.
+    $missing[$type][$name] = TRUE;
+    if (\Drupal::hasService('cache.bootstrap')) {
+      \Drupal::cache('bootstrap')->set('drupal_get_filename:missing', $missing, REQUEST_TIME + 24 * 60 * 60);
+    }
+    trigger_error(SafeMarkup::format('The following @type is missing from the file system: @name', array('@type' => $type, '@name' => $name)), E_USER_WARNING);
+  }
 }
 
 /**
diff --git a/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php b/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php
index 3cb8ab0..0285432 100644
--- a/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php
+++ b/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php
@@ -27,7 +27,6 @@ class CommentStringIdEntitiesTest extends KernelTestBase {
     'user',
     'field',
     'field_ui',
-    'entity',
     'entity_test',
     'text',
   );
diff --git a/core/modules/system/src/Controller/SystemController.php b/core/modules/system/src/Controller/SystemController.php
index 73180a0..d90eb0b 100644
--- a/core/modules/system/src/Controller/SystemController.php
+++ b/core/modules/system/src/Controller/SystemController.php
@@ -15,6 +15,7 @@
 use Drupal\Core\Menu\MenuLinkTreeInterface;
 use Drupal\Core\Menu\MenuTreeParameters;
 use Drupal\Core\Theme\ThemeAccessCheck;
+use Drupal\Core\Cache;
 use Drupal\Core\Url;
 use Drupal\system\SystemManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -67,6 +68,13 @@ class SystemController extends ControllerBase {
   protected $menuLinkTree;
 
   /**
+   * The bootstrap cache service.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $bootstrapCache;
+
+  /**
    * Constructs a new SystemController.
    *
    * @param \Drupal\system\SystemManager $systemManager
@@ -81,14 +89,17 @@ class SystemController extends ControllerBase {
    *   The theme handler.
    * @param \Drupal\Core\Menu\MenuLinkTreeInterface
    *   The menu link tree service.
+   * @parm \Drupal\Core\Cache\CacheBackendInterface
+   *   The bootstrap cache service.
    */
-  public function __construct(SystemManager $systemManager, QueryFactory $queryFactory, ThemeAccessCheck $theme_access, FormBuilderInterface $form_builder, ThemeHandlerInterface $theme_handler, MenuLinkTreeInterface $menu_link_tree) {
+  public function __construct(SystemManager $systemManager, QueryFactory $queryFactory, ThemeAccessCheck $theme_access, FormBuilderInterface $form_builder, ThemeHandlerInterface $theme_handler, MenuLinkTreeInterface $menu_link_tree, CacheBackendInterface $bootstrap_cache) {
     $this->systemManager = $systemManager;
     $this->queryFactory = $queryFactory;
     $this->themeAccess = $theme_access;
     $this->formBuilder = $form_builder;
     $this->themeHandler = $theme_handler;
     $this->menuLinkTree = $menu_link_tree;
+    $this->bootstrapCache = $bootstrap_cache;
   }
 
   /**
@@ -102,6 +113,7 @@ public static function create(ContainerInterface $container) {
       $container->get('form_builder'),
       $container->get('theme_handler'),
       $container->get('menu.link_tree')
+      $container->get('cache.bootstrap')
     );
   }
 
@@ -186,6 +198,10 @@ public function systemAdminMenuBlockPage() {
    * @todo Move into ThemeController.
    */
   public function themesPage() {
+    //  Clean up the bootstrap "missing files" cache when listing themes.
+    $this->bootstrapCache->delete('drupal_get_filename:missing');
+    drupal_static_reset('drupal_get_filename:missing');
+
     $config = $this->config('system.theme');
     // Get all available themes.
     $themes = $this->themeHandler->rebuildThemeData();
diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php
index eb894f6..f07a0ed 100644
--- a/core/modules/system/src/Form/ModulesListForm.php
+++ b/core/modules/system/src/Form/ModulesListForm.php
@@ -174,6 +174,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // Include system.admin.inc so we can use the sort callbacks.
     $this->moduleHandler->loadInclude('system', 'inc', 'system.admin');
 
+    //  Clean up the "missing files" cache when listing modules.
+    \Drupal::cache('bootstrap')->delete('drupal_get_filename:missing');
+    drupal_static_reset('drupal_get_filename:missing');
+
     $form['filters'] = array(
       '#type' => 'container',
       '#attributes' => array(
diff --git a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
index f867045..2291cb7 100644
--- a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
+++ b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
@@ -70,7 +70,26 @@ function testDrupalGetFilename() {
     // a fixed location and naming.
     $this->assertIdentical(drupal_get_filename('profile', 'standard'), 'core/profiles/standard/standard.info.yml');
 
+    // Generate a non-existing module name.
+    $non_existing_module = uniqid("", TRUE);
+
+    // Set a custom error handler so we can ignore the file not found error.
+    set_error_handler(function($severity, $message, $file, $line) {
+      // Skip error handling if this is a "file not found" error.
+      if (!(error_reporting() & $severity) || strstr($message, 'is missing from the file system:')) {
+        return;
+      }
+      throw new ErrorException($message, 0, $severity, $file, $line);
+    });
     // Searching for an item that does not exist returns NULL.
-    $this->assertNull(drupal_get_filename('module', uniqid("", TRUE)), 'Searching for an item that does not exist returns NULL.');
+    $this->assertNull(drupal_get_filename('module', $non_existing_module), 'Searching for an item that does not exist returns NULL.');
+    // Restore the original error handler.
+    restore_error_handler();
+
+    // Get the missing records static from drupal_get_filename.
+    $missing = &drupal_static('drupal_get_filename:missing');
+
+    // Searching for an item that does not exist creates a static record in drupal_get_filename.
+    $this->assertTrue($missing['module'][$non_existing_module], 'Searching for an item that does not exist creates a static record in drupal_get_filename.');
   }
 }
diff --git a/core/modules/system/src/Tests/Common/AttachedAssetsTest.php b/core/modules/system/src/Tests/Common/AttachedAssetsTest.php
index a52db9b..6b83f32 100644
--- a/core/modules/system/src/Tests/Common/AttachedAssetsTest.php
+++ b/core/modules/system/src/Tests/Common/AttachedAssetsTest.php
@@ -74,10 +74,20 @@ function testDefault() {
    * Tests non-existing libraries.
    */
   function testLibraryUnknown() {
+    // Set a custom error handler so we can ignore the file not found error.
+    set_error_handler(function($severity, $message, $file, $line) {
+      // Skip error handling if this is a "file not found" error.
+      if (!(error_reporting() & $severity) || strstr($message, 'is missing from the file system:')) {
+        return;
+      }
+      throw new ErrorException($message, 0, $severity, $file, $line);
+    });
     $build['#attached']['library'][] = 'unknown/unknown';
     $assets = AttachedAssets::createFromRenderArray($build);
 
     $this->assertIdentical([], $this->assetResolver->getJsAssets($assets, FALSE)[0], 'Unknown library was not added to the page.');
+    // Restore the original error handler.
+    restore_error_handler();
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Entity/EntitySchemaTest.php b/core/modules/system/src/Tests/Entity/EntitySchemaTest.php
index 6f6f39d..25ff4f5 100644
--- a/core/modules/system/src/Tests/Entity/EntitySchemaTest.php
+++ b/core/modules/system/src/Tests/Entity/EntitySchemaTest.php
@@ -28,7 +28,7 @@ class EntitySchemaTest extends EntityUnitTestBase  {
    *
    * @var array
    */
-  public static $modules = array('menu_link');
+  public static $modules = array('menu_link_content');
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/taxonomy/src/Tests/TermKernelTest.php b/core/modules/taxonomy/src/Tests/TermKernelTest.php
index 6692775..3d08826 100644
--- a/core/modules/taxonomy/src/Tests/TermKernelTest.php
+++ b/core/modules/taxonomy/src/Tests/TermKernelTest.php
@@ -23,7 +23,7 @@ class TermKernelTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = array( 'filter', 'taxonomy', 'taxonomy_term', 'text', 'user' );
+  public static $modules = array( 'filter', 'taxonomy', 'text', 'user' );
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/views/src/Tests/Plugin/RowEntityTest.php b/core/modules/views/src/Tests/Plugin/RowEntityTest.php
index 35bd1e2..7de0305 100644
--- a/core/modules/views/src/Tests/Plugin/RowEntityTest.php
+++ b/core/modules/views/src/Tests/Plugin/RowEntityTest.php
@@ -24,7 +24,7 @@ class RowEntityTest extends ViewUnitTestBase {
    *
    * @var array
    */
-  public static $modules = ['taxonomy', 'text', 'filter', 'field', 'entity', 'system', 'node', 'user'];
+  public static $modules = ['taxonomy', 'text', 'filter', 'field', 'system', 'node', 'user'];
 
   /**
    * Views used by this test.
