diff --git a/src/IgnoredPathsIteratorFilter.php b/src/IgnoredPathsIteratorFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..e673263d96833691e6f0956f1f6bb62511e341a3
--- /dev/null
+++ b/src/IgnoredPathsIteratorFilter.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\automatic_updates;
+
+/**
+ * Provides an iterator filter for file paths which are ignored.
+ */
+class IgnoredPathsIteratorFilter extends \FilterIterator {
+  use IgnoredPathsTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function accept() {
+    return !$this->isIgnoredPath($this->current());
+  }
+
+}
diff --git a/src/ReadinessChecker/ModifiedFiles.php b/src/ReadinessChecker/ModifiedFiles.php
index 99c041d1af049af915e7cc06fe70a62a28ed4bc5..c96e25e230d53ef29066f2866cf506f6e7747b51 100644
--- a/src/ReadinessChecker/ModifiedFiles.php
+++ b/src/ReadinessChecker/ModifiedFiles.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\automatic_updates\ReadinessChecker;
 
+use Drupal\automatic_updates\IgnoredPathsIteratorFilter;
 use Drupal\automatic_updates\ProjectInfoTrait;
 use Drupal\automatic_updates\Services\ModifiedFilesInterface;
 use Drupal\Core\Extension\ExtensionList;
@@ -92,7 +93,8 @@ class ModifiedFiles implements ReadinessCheckerInterface {
         }
       }
     }
-    foreach ($this->modifiedFiles->getModifiedFiles($extensions) as $file) {
+    $filtered_modified_files = new IgnoredPathsIteratorFilter($this->modifiedFiles->getModifiedFiles($extensions));
+    foreach ($filtered_modified_files as $file) {
       $messages[] = $this->t('The hash for @file does not match its original. Updates that include that file will fail and require manual intervention.', ['@file' => $file]);
     }
     return $messages;
diff --git a/src/Services/ModifiedFiles.php b/src/Services/ModifiedFiles.php
index 955d754e21bcc32d9a5125b15036e3b4d86c5170..5a0fe77f8311578cc5417ea636f2ef290f621627 100644
--- a/src/Services/ModifiedFiles.php
+++ b/src/Services/ModifiedFiles.php
@@ -74,13 +74,13 @@ class ModifiedFiles implements ModifiedFilesInterface {
    * {@inheritdoc}
    */
   public function getModifiedFiles(array $extensions = []) {
-    $modified_files = [];
+    $modified_files = new \ArrayIterator();
     /** @var \GuzzleHttp\Promise\PromiseInterface[] $promises */
     $promises = $this->getHashRequests($extensions);
     // Wait until all the requests are finished.
     (new EachPromise($promises, [
       'concurrency' => 4,
-      'fulfilled' => function ($resource) use (&$modified_files) {
+      'fulfilled' => function ($resource) use ($modified_files) {
         $this->processHashes($resource, $modified_files);
       },
     ]))->promise()->wait();
@@ -92,10 +92,10 @@ class ModifiedFiles implements ModifiedFilesInterface {
    *
    * @param array $resource
    *   An array of http response and project info.
-   * @param array $modified_files
+   * @param \ArrayIterator $modified_files
    *   The list of modified files.
    */
-  protected function processHashes(array $resource, array &$modified_files) {
+  protected function processHashes(array $resource, \ArrayIterator $modified_files) {
     $contents = $resource['contents'];
     $info = $resource['info'];
     $directory_root = $info['install path'];
@@ -112,16 +112,13 @@ class ModifiedFiles implements ModifiedFilesInterface {
         $directory_root,
         $failed_checksum->filename,
       ]));
-      if ($this->isIgnoredPath($file_path)) {
-        continue;
-      }
       if (!file_exists($file_path)) {
-        $modified_files[] = $file_path;
+        $modified_files->append($file_path);
         continue;
       }
       $actual_hash = @hash_file(strtolower($failed_checksum->algorithm), $file_path);
       if ($actual_hash === FALSE || empty($actual_hash) || strlen($actual_hash) < 64 || strcmp($actual_hash, $failed_checksum->hex_hash) !== 0) {
-        $modified_files[] = $file_path;
+        $modified_files->append($file_path);
       }
     }
   }
diff --git a/src/Services/ModifiedFilesInterface.php b/src/Services/ModifiedFilesInterface.php
index 982bd3ed425afc4bac2064c5b371a6ef09efa56e..ba46f254ee7d6c7c6eb6203118d3f3a1906326b5 100644
--- a/src/Services/ModifiedFilesInterface.php
+++ b/src/Services/ModifiedFilesInterface.php
@@ -14,7 +14,7 @@ interface ModifiedFilesInterface {
    *   The list of extensions, keyed by extension name with values an info
    *   array.
    *
-   * @return array
+   * @return \Iterator
    *   The modified files.
    */
   public function getModifiedFiles(array $extensions = []);
diff --git a/tests/modules/test_automatic_updates/src/Controller/ModifiedFilesController.php b/tests/modules/test_automatic_updates/src/Controller/ModifiedFilesController.php
index ef80d1c243b712c1272c7b7f8942da4e557016c3..e1c6622f5cca0ae190c4f2e4417037cd45453ff4 100644
--- a/tests/modules/test_automatic_updates/src/Controller/ModifiedFilesController.php
+++ b/tests/modules/test_automatic_updates/src/Controller/ModifiedFilesController.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\test_automatic_updates\Controller;
 
+use Drupal\automatic_updates\IgnoredPathsIteratorFilter;
 use Drupal\automatic_updates\ProjectInfoTrait;
 use Drupal\automatic_updates\Services\ModifiedFilesInterface;
 use Drupal\Core\Controller\ControllerBase;
@@ -68,9 +69,9 @@ class ModifiedFilesController extends ControllerBase {
     }
 
     $response = Response::create('No modified files!');
-    $messages = $this->modifiedFiles->getModifiedFiles($extensions);
-    if (!empty($messages)) {
-      $response->setContent('Modified files include: ' . implode(', ', $messages));
+    $filtered_modified_files = new IgnoredPathsIteratorFilter($this->modifiedFiles->getModifiedFiles($extensions));
+    if (iterator_count($filtered_modified_files)) {
+      $response->setContent('Modified files include: ' . implode(', ', iterator_to_array($filtered_modified_files)));
     }
     return $response;
   }
diff --git a/tests/src/Build/InPlaceUpdateTest.php b/tests/src/Build/InPlaceUpdateTest.php
index d2040ed7df77491df5ef59bc37decd0f1004c0f4..c72624bab2ca24bed3f1990db7b3695eed9b4781 100644
--- a/tests/src/Build/InPlaceUpdateTest.php
+++ b/tests/src/Build/InPlaceUpdateTest.php
@@ -61,7 +61,7 @@ class InPlaceUpdateTest extends QuickStartTestBase {
     $fs->chmod($this->getWorkspaceDirectory() . '/sites/default', 0700, 0000);
     $this->executeCommand('COMPOSER_DISCARD_CHANGES=true composer install --no-dev --no-interaction');
     $this->assertErrorOutputContains('Generating autoload files');
-    $this->executeCommand('COMPOSER_DISCARD_CHANGES=true composer require ocramius/package-versions:^1.4 webflo/drupal-finder:^1.1 composer/semver:^1.0 --no-interaction');
+    $this->executeCommand('COMPOSER_DISCARD_CHANGES=true composer require ocramius/package-versions:^1.4 webflo/drupal-finder:^1.1 composer/semver:^1.0 drupal/php-signify:^1.0@dev --no-interaction');
     $this->assertErrorOutputContains('Generating autoload files');
     $this->installQuickStart('minimal');
 
@@ -120,7 +120,7 @@ class InPlaceUpdateTest extends QuickStartTestBase {
     $fs->chmod($this->getWorkspaceDirectory() . '/sites/default', 0700, 0000);
     $this->executeCommand('COMPOSER_DISCARD_CHANGES=true composer install --no-dev --no-interaction');
     $this->assertErrorOutputContains('Generating autoload files');
-    $this->executeCommand('COMPOSER_DISCARD_CHANGES=true composer require ocramius/package-versions:^1.4 webflo/drupal-finder:^1.1 composer/semver:^1.0 --no-interaction');
+    $this->executeCommand('COMPOSER_DISCARD_CHANGES=true composer require ocramius/package-versions:^1.4 webflo/drupal-finder:^1.1 composer/semver:^1.0 drupal/php-signify:^1.0@dev --no-interaction');
     $this->assertErrorOutputContains('Generating autoload files');
     $this->installQuickStart('standard');
 
diff --git a/tests/src/Build/ModifiedFilesTest.php b/tests/src/Build/ModifiedFilesTest.php
index b8d3ae2271d543c9227ebba4429d28af9ceddea5..9b973d23292b8f9e8baa3096c076ccf3c26b95c8 100644
--- a/tests/src/Build/ModifiedFilesTest.php
+++ b/tests/src/Build/ModifiedFilesTest.php
@@ -114,7 +114,6 @@ class ModifiedFilesTest extends QuickStartTestBase {
    *   The modified files to assert.
    */
   protected function assertModifications($project_type, $project, array $modifications) {
-    $this->destroyBuild = FALSE;
     $this->symfonyFileSystem->chmod($this->getWorkspaceDirectory() . '/sites/default', 0700, 0000);
     $this->executeCommand('COMPOSER_DISCARD_CHANGES=true composer install --no-dev --no-interaction');
     $this->assertErrorOutputContains('Generating autoload files');
diff --git a/tests/src/Kernel/ReadinessChecker/ModifiedFilesTest.php b/tests/src/Kernel/ReadinessChecker/ModifiedFilesTest.php
index fa5266ee6ee41fdadc9db001b2e2ec4ee7c88fd7..79e72b9ee4339e938b59a3225a1c42f4e0d19390 100644
--- a/tests/src/Kernel/ReadinessChecker/ModifiedFilesTest.php
+++ b/tests/src/Kernel/ReadinessChecker/ModifiedFilesTest.php
@@ -28,7 +28,7 @@ class ModifiedFilesTest extends KernelTestBase {
   public function testModifiedFiles() {
     /** @var \Prophecy\Prophecy\ObjectProphecy|\Drupal\automatic_updates\Services\ModifiedFilesInterface $service */
     $service = $this->prophesize(ModifiedFilesInterface::class);
-    $service->getModifiedFiles(Argument::type('array'))->willReturn([]);
+    $service->getModifiedFiles(Argument::type('array'))->willReturn(new \ArrayIterator());
     $modules = $this->container->get('extension.list.module');
     $profiles = $this->container->get('extension.list.profile');
     $themes = $this->container->get('extension.list.theme');
@@ -44,7 +44,7 @@ class ModifiedFilesTest extends KernelTestBase {
     $this->assertEmpty($messages);
 
     // Hash doesn't match i.e. modified code.
-    $service->getModifiedFiles(Argument::type('array'))->willReturn(['core/LICENSE.txt']);
+    $service->getModifiedFiles(Argument::type('array'))->willReturn(new \ArrayIterator(['core/LICENSE.txt']));
     $messages = $modified_files->run();
     $this->assertCount(1, $messages);
   }