diff --git a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
index 5ee4adbe032dd26477c31595ed1af48af14a7dd5..0208e7c495f8064d8a0ac1ccddd1c81d55608a13 100644
--- a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
@@ -135,6 +135,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     // Prevent this page from showing when the module list is empty.
     if (empty($this->modules)) {
+      drupal_set_message($this->t('The selected modules could not be uninstalled, either due to a website problem or due to the uninstall confirmation form timing out. Please try again.'), 'error');
       return $this->redirect('system.modules_uninstall');
     }
 
diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php
index 153e2caf8eb7e62732f3db9adfe3d3bf9e15007d..f72fa4330250a8f72f525f496695bc7d96b61f88 100644
--- a/core/modules/system/src/Form/ModulesUninstallForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallForm.php
@@ -171,7 +171,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   public function validateForm(array &$form, FormStateInterface $form_state) {
     // Form submitted, but no modules selected.
     if (!array_filter($form_state->getValue('uninstall'))) {
-      drupal_set_message($this->t('No modules selected.'), 'error');
+      $form_state->setErrorByName('uninstall', $this->t('No modules selected.'));
       $form_state->setRedirect('system.modules_uninstall');
     }
   }
@@ -184,7 +184,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $modules = $form_state->getValue('uninstall');
     $uninstall = array_keys(array_filter($modules));
     $account = $this->currentUser()->id();
-    $this->keyValueExpirable->setWithExpire($account, $uninstall, 60);
+    // Store the values for 6 hours. This expiration time is also used in
+    // the form cache.
+    $this->keyValueExpirable->setWithExpire($account, $uninstall, 6*60*60);
 
     // Redirect to the confirm form.
     $form_state->setRedirect('system.modules_uninstall_confirm');
diff --git a/core/modules/system/src/Tests/Module/UninstallTest.php b/core/modules/system/src/Tests/Module/UninstallTest.php
index c7eb051c38575bee37b4b52aa18f2cc8d58e5185..e43a674e1253474dda2f9ad23070841b0ab2f83f 100644
--- a/core/modules/system/src/Tests/Module/UninstallTest.php
+++ b/core/modules/system/src/Tests/Module/UninstallTest.php
@@ -106,6 +106,10 @@ function testUninstallPage() {
     // Make sure our unique cache entry is gone.
     $cached = \Drupal::cache()->get('uninstall_test');
     $this->assertFalse($cached, 'Cache entry not found');
+    // Make sure we get an error message when we try to confirm uninstallation
+    // of an empty list of modules.
+    $this->drupalGet('admin/modules/uninstall/confirm');
+    $this->assertText(t('The selected modules could not be uninstalled, either due to a website problem or due to the uninstall confirmation form timing out. Please try again.'), 'Module uninstall confirmation form displays error message');
 
     // Make sure confirmation page is accessible only during uninstall process.
     $this->drupalGet('admin/modules/uninstall/confirm');