diff --git a/ReadinessCheckers/MissingProjectInfo.php b/ReadinessCheckers/MissingProjectInfo.php
new file mode 100644
index 0000000..38d5616
--- /dev/null
+++ b/ReadinessCheckers/MissingProjectInfo.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * Missing project info checker.
+ */
+class MissingProjectInfo implements ReadinessCheckerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function run() {
+    return static::missingProjectInfoCheck();
+  }
+
+  /**
+   * Check for projects missing project info.
+   *
+   * @return array
+   *   An array of translatable strings if any checks fail.
+   */
+  protected static function missingProjectInfoCheck() {
+    $messages = [];
+    foreach (static::getInfos() as $extension_name => $info) {
+      if (static::isIgnoredPath(drupal_get_path($info['type'], $extension_name))) {
+        continue;
+      }
+      if (!static::getExtensionVersion($extension_name, $info)) {
+        $messages[] = t('The project "@extension" can not be updated because its version is either undefined or a dev release.', ['@extension' => $extension_name]);
+      }
+    }
+    return $messages;
+  }
+
+  /**
+   * Get the extension types.
+   *
+   * @return array
+   *   The extension types.
+   */
+  protected static function getExtensionsTypes() {
+    return ['modules', 'profiles', 'themes'];
+  }
+
+  /**
+   * Returns an array of info files information of available extensions.
+   *
+   * @return array
+   *   An associative array of extension information arrays, keyed by extension
+   *   name.
+   */
+  protected static function getInfos() {
+    $infos = [];
+    // Find extensions.
+    $extensions = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'modules', $key = 'name', $min_depth = 1);
+    $extensions = array_merge($extensions, drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'themes', $key = 'name', $min_depth = 1));
+    foreach ($extensions as $extension) {
+      if (file_exists($info_file = dirname($extension->uri) . '/' . $extension->name . '.info')) {
+        // Get the .info file for the module or theme this file belongs to.
+        $infos[$extension->name] = drupal_parse_info_file($info_file);
+      }
+    }
+
+    return $infos;
+  }
+
+  /**
+   * Get the extension version.
+   *
+   * @param string $extension_name
+   *   The extension name.
+   * @param array $info
+   *   The extension's info.
+   *
+   * @return string|null
+   *   The version or NULL if undefined.
+   */
+  protected static function getExtensionVersion($extension_name, array $info) {
+    if (isset($info['version']) && strpos($info['version'], '-dev') === FALSE) {
+      return $info['version'];
+    }
+  }
+
+  /**
+   * Check if the file path is ignored.
+   *
+   * @param string $file_path
+   *   The file path.
+   *
+   * @return bool
+   *   TRUE if file path is ignored, else FALSE.
+   */
+  protected static function isIgnoredPath($file_path) {
+    $paths = variable_get('automatic_updates_ignored_paths', "sites/all/modules/custom/*\nsites/all/themes/custom/*");
+    if (drupal_match_path($file_path, $paths)) {
+      return TRUE;
+    }
+  }
+}
diff --git a/ReadinessCheckers/ReadinessCheckerManager.php b/ReadinessCheckers/ReadinessCheckerManager.php
index 98c5a6b..d7b9442 100644
--- a/ReadinessCheckers/ReadinessCheckerManager.php
+++ b/ReadinessCheckers/ReadinessCheckerManager.php
@@ -22,6 +22,7 @@ class ReadinessCheckerManager {
    *   The registered checkers.
    */
   protected static function getCheckers() {
+    static::$checkers['warning'][0][] = 'MissingProjectInfo';
     static::$checkers['warning'][0][] = 'PhpSapi';
     static::$checkers['error'][0][] = 'PhpSapi';
 
diff --git a/automatic_updates.admin.inc b/automatic_updates.admin.inc
index 20aa1b4..acbffcf 100644
--- a/automatic_updates.admin.inc
+++ b/automatic_updates.admin.inc
@@ -33,7 +33,7 @@ function automatic_updates_admin_form() {
     '#type' => 'textarea',
     '#title' => t('Paths to ignore for readiness checks'),
     '#description' => t('Paths relative to %drupal_root. One path per line.', ['%drupal_root' => DRUPAL_ROOT]),
-    '#default_value' => variable_get('automatic_updates_ignored_paths', "modules/custom/*\nthemes/custom/*\nprofiles/custom/*"),
+    '#default_value' => variable_get('automatic_updates_ignored_paths', "sites/all/modules/custom/*\nsites/all/themes/custom/*"),
     '#states' => [
       'visible' => [
         ':input[name="automatic_updates_enable_readiness_checks"]' => ['checked' => TRUE],
diff --git a/automatic_updates.info b/automatic_updates.info
index 2fc0995..d93586e 100644
--- a/automatic_updates.info
+++ b/automatic_updates.info
@@ -8,4 +8,5 @@ files[] = tests/automatic_updates.test
 files[] = AutomaticUpdatesPsa.php
 files[] = ReadinessCheckers/ReadinessCheckerManager.php
 files[] = ReadinessCheckers/ReadinessCheckerInterface.php
+files[] = ReadinessCheckers/MissingProjectInfo.php
 files[] = ReadinessCheckers/PhpSapi.php
