diff --git a/core/modules/inline_form_errors/inline_form_errors.module b/core/modules/inline_form_errors/inline_form_errors.module
index 52e572d300..ef9b63b1a5 100644
--- a/core/modules/inline_form_errors/inline_form_errors.module
+++ b/core/modules/inline_form_errors/inline_form_errors.module
@@ -49,6 +49,15 @@ function inline_form_errors_preprocess_datetime_wrapper(&$variables) {
 }
 
 /**
+ * Implements hook_preprocess_HOOK() for system modules uninstall templates.
+ */
+function inline_form_errors_preprocess_system_modules_uninstall(&$variables) {
+  if (!empty($variables['form']['uninstall']['#errors']) && empty($element['#error_no_message'])) {
+    $variables['errors'] = $variables['form']['uninstall']['#errors'];
+  }
+}
+
+/**
  * Populates form errors in the template.
  */
 function _inline_form_errors_set_errors(&$variables) {
diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php
index a06810ef0b..39f380e617 100644
--- a/core/modules/system/src/Form/ModulesUninstallForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallForm.php
@@ -131,6 +131,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         '#type' => 'checkbox',
         '#title' => $this->t('Uninstall @module module', array('@module' => $name)),
         '#title_display' => 'invisible',
+        '#error_no_message' => TRUE,
       );
 
       // If a validator returns reasons not to uninstall a module,
diff --git a/core/modules/system/templates/system-modules-uninstall.html.twig b/core/modules/system/templates/system-modules-uninstall.html.twig
index 180ca08e41..683b4c1a33 100644
--- a/core/modules/system/templates/system-modules-uninstall.html.twig
+++ b/core/modules/system/templates/system-modules-uninstall.html.twig
@@ -23,6 +23,12 @@
 #}
 {{ form.filters }}
 
+{% if errors %}
+  <div class="form-item--error-message">
+    <strong>{{ errors }}</strong>
+  </div>
+{% endif %}
+
 <table class="responsive-enabled" data-striping="1">
   <thead>
     <tr>
diff --git a/core/themes/seven/templates/system-modules-uninstall.html.twig b/core/themes/seven/templates/system-modules-uninstall.html.twig
new file mode 100644
index 0000000000..f2c1e5a9d0
--- /dev/null
+++ b/core/themes/seven/templates/system-modules-uninstall.html.twig
@@ -0,0 +1,79 @@
+{#
+/**
+ * @file
+ * Theme override for the modules uninstall page.
+ *
+ * Available variables:
+ * - form: The modules uninstall form.
+ * - modules: Contains multiple module instances. Each module contains:
+ *   - attributes: Attributes on the row.
+ *   - module_name: The name of the module.
+ *   - checkbox: A checkbox for uninstalling the module.
+ *   - checkbox_id: A unique identifier for interacting with the checkbox
+ *     element.
+ *   - name: The human-readable name of the module.
+ *   - description: The description of the module.
+ *   - disabled_reasons: (optional) A list of reasons why this module cannot be
+ *     uninstalled.
+ *
+ * @see template_preprocess_system_modules_uninstall()
+ */
+#}
+{{ form.filters }}
+
+{% if errors %}
+  <div class="form-item--error-message">
+    <strong>{{ errors }}</strong>
+  </div>
+{% endif %}
+
+<table class="responsive-enabled" data-striping="1">
+  <thead>
+    <tr>
+      <th>{{ 'Uninstall'|t }}</th>
+      <th>{{ 'Name'|t }}</th>
+      <th>{{ 'Description'|t }}</th>
+    </tr>
+  </thead>
+  <tbody>
+    {% for module in modules %}
+      {% set zebra = cycle(['odd', 'even'], loop.index0) -%}
+      <tr{{ module.attributes.addClass(zebra) }}>
+        <td align="center">
+          {{- module.checkbox -}}
+        </td>
+        <td>
+          <label for="{{ module.checkbox_id }}" class="module-name table-filter-text-source">{{ module.name }}</label>
+        </td>
+        <td class="description">
+          <span class="text module-description">{{ module.description }}</span>
+          {% if module.reasons_count > 0 %}
+            <div class="admin-requirements">
+              {%- trans -%}
+                The following reason prevents {{ module.module_name }} from being uninstalled:
+              {%- plural module.reasons_count -%}
+                The following reasons prevent {{ module.module_name }} from being uninstalled:
+              {%- endtrans %}
+              <div class="item-list">
+                <ul>
+                  {%- for reason in module.validation_reasons -%}
+                    <li>{{ reason }}</li>
+                  {%- endfor -%}
+                  {%- if module.required_by -%}
+                    <li>{{ 'Required by: @module-list'|t({'@module-list': module.required_by|safe_join(', ') }) }}</li>
+                  {%- endif -%}
+                </ul>
+              </div>
+            </div>
+          {% endif %}
+        </td>
+      </tr>
+    {% else %}
+      <tr class="odd">
+        <td colspan="3" class="empty message">{{ 'No modules are available to uninstall.'|t }}</td>
+      </tr>
+    {% endfor %}
+  </tbody>
+</table>
+
+{{ form|without('filters', 'modules', 'uninstall') }}
