diff --git a/core/lib/Drupal/Core/Command/GenerateTheme.php b/core/lib/Drupal/Core/Command/GenerateTheme.php
index e613358f2b19cfa09d7787a37bb9b9d5e84dd869..bb09d380aed4f4911496c4f7ab96425980a7a695 100644
--- a/core/lib/Drupal/Core/Command/GenerateTheme.php
+++ b/core/lib/Drupal/Core/Command/GenerateTheme.php
@@ -252,9 +252,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
       }
     }
 
-    if (!rename($tmp_dir, $destination)) {
-      $io->getErrorStyle()->error("The theme could not be moved to the destination: $destination.");
-      return 1;
+    if (!@rename($tmp_dir, $destination)) {
+      // If rename fails, copy the files to the destination directory. This is
+      // expected to happen when the tmp directory is on a different file
+      // system.
+      $this->copyRecursive($tmp_dir, $destination);
+
+      // Renaming would not have left anything behind. Ensure that is still the
+      // case.
+      $this->rmRecursive($tmp_dir);
     }
 
     $output->writeln(sprintf('Theme generated successfully to %s', $destination));
@@ -262,6 +268,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int
     return 0;
   }
 
+  /**
+   * Removes a directory recursively.
+   *
+   * @param string $dir
+   *   A directory to be removed.
+   */
+  private function rmRecursive(string $dir): void {
+    $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
+    foreach ($files as $file) {
+      is_dir($file) ? rmdir($file) : unlink($file);
+    }
+  }
+
   /**
    * Copies files recursively.
    *