diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 26a75f6..3493ba2 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 bad 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['bad'] = &drupal_static(__FUNCTION__ . ':bad');
+  }
+  $bad = &$drupal_static_fast['bad'];
+
   // 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 (is_null($bad)) {
+        $bad = array();
+        if (\Drupal::hasService('cache.bootstrap')) {
+          $cache = Drupal::cache('bootstrap')->get('drupal_get_filename:bad', TRUE);
+          if ($cache && $cache->data) {
+            $bad = $cache->data;
+          }
+        }
       }
-      foreach ($listing->scan($original_type) as $extension_name => $file) {
-        $files[$type][$extension_name] = $file->getPathname();
+      if (!isset($bad[$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($bad[$type][$name])) {
+    // Add the missing file to a temporary cache and throw an alert.
+    $bad[$type][$name] = TRUE;
+    if (\Drupal::hasService('cache.bootstrap')) {
+      \Drupal::cache('bootstrap')->set('drupal_get_filename:bad', $bad, REQUEST_TIME);
+    }
+    if (\Drupal::hasService('logger.factory')) {
+      \Drupal::logger('system')->error('The following @type is missing from the file system: @name', array('@type' => $type, '@name' => $name));
+    }
+  }
 }
 
 /**
diff --git a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
index f867045..1220359 100644
--- a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
+++ b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php
@@ -70,7 +70,16 @@ 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);
+
     // 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.');
+
+    // Get the bad records static from drupal_get_filename.
+    $bad = &drupal_static('drupal_get_filename:bad');
+
+    // Searching for an item that does not exist creates a static record in drupal_get_filename.
+    $this->assertTrue($bad['module'][$non_existing_module], 'Searching for an item that does not exist creates a static record in drupal_get_filename.');
   }
 }
