diff --git a/core/core.services.yml b/core/core.services.yml
index 4e3749a5e185d675de09688deefcd5f5f1487551..e73b944301bc98edb3aa367bf714518730542bb9 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1554,7 +1554,7 @@ services:
   Drupal\Core\Theme\ThemeInitializationInterface: '@theme.initialization'
   theme.registry:
     class: Drupal\Core\Theme\Registry
-    arguments: ['%app.root%', '@cache.default', '@lock', '@module_handler', '@theme_handler', '@theme.initialization', '@cache.bootstrap', '@extension.list.module']
+    arguments: ['%app.root%', '@cache.default', '@lock', '@module_handler', '@theme_handler', '@theme.initialization', '@cache.bootstrap', '@extension.list.module', '@kernel']
     tags:
       - { name: needs_destruction }
     calls:
diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php
index e72de8be75eb29c5804502cf7d9eb0c7b4a1adc7..d4f02d7108ec931cd4cccaff78a6262d41b10136 100644
--- a/core/lib/Drupal/Core/Theme/Registry.php
+++ b/core/lib/Drupal/Core/Theme/Registry.php
@@ -10,7 +10,9 @@
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\Lock\LockBackendInterface;
+use Drupal\Core\Update\UpdateKernel;
 use Drupal\Core\Utility\ThemeRegistry;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
 
 /**
  * Defines the theme registry service.
@@ -178,10 +180,12 @@ class Registry implements DestructableInterface {
    *   The cache backend interface to use for the runtime theme registry data.
    * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
    *   The module list.
+   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $kernel
+   *   The kernel.
    * @param string $theme_name
    *   (optional) The name of the theme for which to construct the registry.
    */
-  public function __construct($root, CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, ThemeInitializationInterface $theme_initialization, CacheBackendInterface $runtime_cache, ModuleExtensionList $module_list, $theme_name = NULL) {
+  public function __construct($root, CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, ThemeInitializationInterface $theme_initialization, CacheBackendInterface $runtime_cache, ModuleExtensionList $module_list, protected HttpKernelInterface $kernel, $theme_name = NULL) {
     $this->root = $root;
     $this->cache = $cache;
     $this->lock = $lock;
@@ -252,11 +256,30 @@ public function get() {
         return $cached;
       }
     }
-    $this->build();
-    // Only persist it if all modules are loaded to ensure it is complete.
-    if ($this->moduleHandler->isLoaded()) {
-      $this->setCache();
+
+    // Some theme hook implementations such as the one in Views request a lot of
+    // information such as field schemas. These might be broken until an update
+    // is run, so we need to build a limited registry while on update.php.
+    if ($this->kernel instanceof UpdateKernel) {
+      $module_list = $this->moduleHandler->getModuleList();
+      $filter_list = array_intersect_key($module_list, ['system' => TRUE]);
+
+      // Call ::build() with only the system module and then revert.
+      $this->moduleHandler->setModuleList($filter_list);
+      $this->build();
+      $this->moduleHandler->setModuleList($module_list);
+
+      // We might have poisoned the cache with only info from 'system'.
+      $this->cache->delete("theme_registry:build:modules");
+    }
+    else {
+      $this->build();
+      // Only persist it if all modules are loaded to ensure it is complete.
+      if ($this->moduleHandler->isLoaded()) {
+        $this->setCache();
+      }
     }
+
     return $this->registry[$this->theme->getName()];
   }
 
diff --git a/core/modules/system/src/Theme/DbUpdateNegotiator.php b/core/modules/system/src/Theme/DbUpdateNegotiator.php
index f765412edb72475e9b5bb6145be11fbbf5f9e78f..d80d610c3d9e0a83c2e909cdfe4281933a5538bb 100644
--- a/core/modules/system/src/Theme/DbUpdateNegotiator.php
+++ b/core/modules/system/src/Theme/DbUpdateNegotiator.php
@@ -5,7 +5,6 @@
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Site\Settings;
 use Drupal\Core\Theme\ThemeNegotiatorInterface;
 
 /**
@@ -51,7 +50,8 @@ public function applies(RouteMatchInterface $route_match) {
    * {@inheritdoc}
    */
   public function determineActiveTheme(RouteMatchInterface $route_match) {
-    return Settings::get('maintenance_theme') ?: 'claro';
+    // The update page always uses Claro to ensure stability.
+    return 'claro';
   }
 
 }
diff --git a/core/modules/system/tests/modules/update_test_broken_theme_hook/update_test_broken_theme_hook.info.yml b/core/modules/system/tests/modules/update_test_broken_theme_hook/update_test_broken_theme_hook.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6ed5a95cc6f4552f9fb25015dfe96f030399c765
--- /dev/null
+++ b/core/modules/system/tests/modules/update_test_broken_theme_hook/update_test_broken_theme_hook.info.yml
@@ -0,0 +1,5 @@
+name: 'Update test with broken theme hook'
+type: module
+description: 'Support module for update testing.'
+package: Testing
+version: VERSION
diff --git a/core/modules/system/tests/modules/update_test_broken_theme_hook/update_test_broken_theme_hook.module b/core/modules/system/tests/modules/update_test_broken_theme_hook/update_test_broken_theme_hook.module
new file mode 100644
index 0000000000000000000000000000000000000000..8758efca08e62349747cf607152c526bc029e796
--- /dev/null
+++ b/core/modules/system/tests/modules/update_test_broken_theme_hook/update_test_broken_theme_hook.module
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Hook implementations for the update_test_broken_theme_hook module.
+ */
+
+/**
+ * Implements hook_theme().
+ */
+function update_test_broken_theme_hook_theme($existing, $type, $theme, $path) {
+  throw new \Exception('This mimics an exception caused by unstable dependencies.');
+}
diff --git a/core/tests/Drupal/FunctionalTests/Update/UpdateReducedThemeRegistryTest.php b/core/tests/Drupal/FunctionalTests/Update/UpdateReducedThemeRegistryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b31d62cc3d03dc37746c209ddc5bf18d61523132
--- /dev/null
+++ b/core/tests/Drupal/FunctionalTests/Update/UpdateReducedThemeRegistryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\FunctionalTests\Update;
+
+use Drupal\Core\Url;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests that update.php is accessible even if there are unstable modules.
+ *
+ * @group Update
+ */
+class UpdateReducedThemeRegistryTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['update_test_broken_theme_hook'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Tests that the update page can be accessed.
+   */
+  public function testUpdatePageWithBrokenThemeHook(): void {
+    require_once $this->root . '/core/includes/update.inc';
+    $this->writeSettings([
+      'settings' => [
+        'update_free_access' => (object) [
+          'value' => TRUE,
+          'required' => TRUE,
+        ],
+      ],
+    ]);
+    $this->drupalGet(Url::fromRoute('system.db_update'));
+    $this->assertSession()->statusCodeEquals(200);
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
index 20d1320c242d473626f65981816fe89bbdd22b11..0a672d6e3218ca71502c340d231125c4b5449205 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
@@ -76,11 +76,11 @@ public function testMultipleSubThemes() {
     $module_list = $this->container->get('extension.list.module');
     assert($module_list instanceof ModuleExtensionList);
 
-    $registry_subsub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $module_list, 'test_subsubtheme');
+    $registry_subsub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $module_list, \Drupal::service('kernel'), 'test_subsubtheme');
     $registry_subsub_theme->setThemeManager(\Drupal::theme());
-    $registry_sub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $module_list, 'test_subtheme');
+    $registry_sub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $module_list, \Drupal::service('kernel'), 'test_subtheme',);
     $registry_sub_theme->setThemeManager(\Drupal::theme());
-    $registry_base_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $module_list, 'test_basetheme');
+    $registry_base_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $module_list, \Drupal::service('kernel'), 'test_basetheme');
     $registry_base_theme->setThemeManager(\Drupal::theme());
 
     $preprocess_functions = $registry_subsub_theme->get()['theme_test_template_test']['preprocess functions'];
@@ -114,7 +114,7 @@ public function testSuggestionPreprocessFunctions() {
 
     $extension_list = $this->container->get('extension.list.module');
     assert($extension_list instanceof ModuleExtensionList);
-    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $extension_list, 'test_theme');
+    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $extension_list, \Drupal::service('kernel'), 'test_theme');
     $registry_theme->setThemeManager(\Drupal::theme());
 
     $suggestions = ['__kitten', '__flamingo'];
@@ -156,7 +156,7 @@ public function testThemeRegistryAlterByTheme() {
 
     $extension_list = $this->container->get('extension.list.module');
     assert($extension_list instanceof ModuleExtensionList);
-    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $extension_list, 'test_theme');
+    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $extension_list, \Drupal::service('kernel'), 'test_theme');
     $registry->setThemeManager(\Drupal::theme());
     $this->assertEquals('value', $registry->get()['theme_test_template_test']['variables']['additional']);
   }
@@ -265,7 +265,7 @@ public function testThemeTemplatesRegisteredByModules() {
 
     $extension_list = \Drupal::service('extension.list.module');
     assert($extension_list instanceof ModuleExtensionList);
-    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $extension_list, 'test_theme');
+    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), $extension_list, \Drupal::service('kernel'), 'test_theme');
     $registry_theme->setThemeManager(\Drupal::theme());
 
     $expected = [
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php
index 22cd470323acef02b138a3ba730bc7a74c3e007f..7f2598e2fa3793f6b2969c7da036ef344c02a67e 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php
@@ -92,7 +92,7 @@ protected function installAllModules() {
    * Ensures that Stable 9 overrides all relevant core templates.
    */
   public function testStable9TemplateOverrides() {
-    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $this->themeHandler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), \Drupal::service('extension.list.module'), 'stable9');
+    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $this->themeHandler, \Drupal::service('theme.initialization'), \Drupal::service('cache.bootstrap'), \Drupal::service('extension.list.module'), \Drupal::service('kernel'), 'stable9');
     $registry->setThemeManager(\Drupal::theme());
 
     $registry_full = $registry->get();
diff --git a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
index 9a4ecb89b61f963f716efa0e71bcd17e6aac8ca7..7f6a63ab81b2c10ee34f6102eea6d4660ce96bd9 100644
--- a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Theme\ActiveTheme;
 use Drupal\Core\Theme\Registry;
 use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
 
 /**
  * @coversDefaultClass \Drupal\Core\Theme\Registry
@@ -78,6 +79,13 @@ class RegistryTest extends UnitTestCase {
    */
   protected $moduleList;
 
+  /**
+   * The kernel.
+   *
+   * @var \Symfony\Component\HttpKernel\HttpKernelInterface|\PHPUnit\Framework\MockObject\MockObject
+   */
+  protected $kernel;
+
   /**
    * The list of functions that get_defined_functions() should provide.
    *
@@ -99,7 +107,8 @@ protected function setUp(): void {
     $this->runtimeCache = $this->createMock('Drupal\Core\Cache\CacheBackendInterface');
     $this->themeManager = $this->createMock('Drupal\Core\Theme\ThemeManagerInterface');
     $this->moduleList = $this->createMock(ModuleExtensionList::class);
-    $this->registry = new Registry($this->root, $this->cache, $this->lock, $this->moduleHandler, $this->themeHandler, $this->themeInitialization, $this->runtimeCache, $this->moduleList);
+    $this->kernel = $this->createMock(HttpKernelInterface::class);
+    $this->registry = new Registry($this->root, $this->cache, $this->lock, $this->moduleHandler, $this->themeHandler, $this->themeInitialization, $this->runtimeCache, $this->moduleList, $this->kernel);
     $this->registry->setThemeManager($this->themeManager);
   }