diff --git a/composer.json b/composer.json
index 3f791a9740c71e0966519e09b0715da37a2ea5e9..2e8cec9d3205207d437e7a807ba929dc924d369b 100644
--- a/composer.json
+++ b/composer.json
@@ -75,7 +75,7 @@
 		"symfony/var-dumper": "^5.2",
 		"symfony/yaml": "^5.2",
 		"typo3/class-alias-loader": "^1.0",
-		"typo3/cms-cli": "^2.0",
+		"typo3/cms-cli": "^3.0",
 		"typo3/cms-composer-installers": "^2.0 || ^3.0",
 		"typo3/phar-stream-wrapper": "^3.1.6",
 		"typo3/symfony-psr-event-dispatcher-adapter": "^1.0 || ^2.0",
diff --git a/composer.lock b/composer.lock
index ecdaeff89dacc3ba9ee4785b7502bd428fa8f223..22157f65aa3725a3e361f0d511b58868719416f2 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "b4c3074ccc16c2e62a19f8ccba3f0998",
+    "content-hash": "ecf8365aa1212f8dec9609b56adab0f2",
     "packages": [
         {
             "name": "bacon/bacon-qr-code",
@@ -4373,16 +4373,16 @@
         },
         {
             "name": "typo3/cms-cli",
-            "version": "2.0.0",
+            "version": "3.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/TYPO3/cms-cli.git",
-                "reference": "215a0bf5c446b4e0b20f4562bbaf3d6215a5ee82"
+                "reference": "bfb13f4ab6a505104662b79c18108f41c48e9288"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/TYPO3/cms-cli/zipball/215a0bf5c446b4e0b20f4562bbaf3d6215a5ee82",
-                "reference": "215a0bf5c446b4e0b20f4562bbaf3d6215a5ee82",
+                "url": "https://api.github.com/repos/TYPO3/cms-cli/zipball/bfb13f4ab6a505104662b79c18108f41c48e9288",
+                "reference": "bfb13f4ab6a505104662b79c18108f41c48e9288",
                 "shasum": ""
             },
             "require": {
@@ -4400,9 +4400,9 @@
             "homepage": "https://typo3.org",
             "support": {
                 "issues": "https://github.com/TYPO3/cms-cli/issues",
-                "source": "https://github.com/TYPO3/cms-cli/tree/master"
+                "source": "https://github.com/TYPO3/cms-cli/tree/3.0.0"
             },
-            "time": "2018-03-08T20:16:43+00:00"
+            "time": "2021-02-09T12:45:27+00:00"
         },
         {
             "name": "typo3/cms-composer-installers",
@@ -4622,12 +4622,12 @@
             "version": "1.9.1",
             "source": {
                 "type": "git",
-                "url": "https://github.com/webmozart/assert.git",
+                "url": "https://github.com/webmozarts/assert.git",
                 "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
+                "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
                 "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
                 "shasum": ""
             },
@@ -4665,8 +4665,8 @@
                 "validate"
             ],
             "support": {
-                "issues": "https://github.com/webmozart/assert/issues",
-                "source": "https://github.com/webmozart/assert/tree/master"
+                "issues": "https://github.com/webmozarts/assert/issues",
+                "source": "https://github.com/webmozarts/assert/tree/1.9.1"
             },
             "time": "2020-07-08T17:02:28+00:00"
         }
diff --git a/typo3/sysext/core/Classes/Command/Descriptor/TextDescriptor.php b/typo3/sysext/core/Classes/Command/Descriptor/TextDescriptor.php
index 8d56392e76e3d295bd37bd670776d6991da3a5f8..62b9d8ed2c73890e821945e772326e490ddc0e9a 100644
--- a/typo3/sysext/core/Classes/Command/Descriptor/TextDescriptor.php
+++ b/typo3/sysext/core/Classes/Command/Descriptor/TextDescriptor.php
@@ -32,10 +32,12 @@ use TYPO3\CMS\Core\Console\CommandRegistry;
 class TextDescriptor extends SymfonyTextDescriptor
 {
     private CommandRegistry $commandRegistry;
+    private bool $degraded;
 
-    public function __construct(CommandRegistry $commandRegistry)
+    public function __construct(CommandRegistry $commandRegistry, bool $degraded)
     {
         $this->commandRegistry = $commandRegistry;
+        $this->degraded = $degraded;
     }
 
     /**
@@ -57,6 +59,10 @@ class TextDescriptor extends SymfonyTextDescriptor
             return;
         }
 
+        if ($this->degraded) {
+            $this->write("<error>Failed to boot dependency injection, only lowlevel commands are available.</error>\n\n", true);
+        }
+
         $namespaces = $this->commandRegistry->getNamespaces();
         $help = $application->getHelp();
         if ($help !== '') {
@@ -89,6 +95,10 @@ class TextDescriptor extends SymfonyTextDescriptor
         }
 
         $this->write("\n");
+
+        if ($this->degraded) {
+            $this->write("\n<error>Failed to boot dependency injection, only lowlevel commands are available.</error>\n", true);
+        }
     }
 
     private function describeNamespace(array $namespace, array $commands, int $width): void
diff --git a/typo3/sysext/core/Classes/Command/ListCommand.php b/typo3/sysext/core/Classes/Command/ListCommand.php
index 193afc6ca7bfbafa67204d30293e041bbc311293..887305c5f1f26d132865e2d7cfee0b315e5f2a28 100644
--- a/typo3/sysext/core/Classes/Command/ListCommand.php
+++ b/typo3/sysext/core/Classes/Command/ListCommand.php
@@ -17,23 +17,27 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Command;
 
+use Psr\Container\ContainerInterface;
 use Symfony\Component\Console\Command\ListCommand as SymfonyListCommand;
 use Symfony\Component\Console\Helper\DescriptorHelper;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
 use TYPO3\CMS\Core\Command\Descriptor\TextDescriptor;
 use TYPO3\CMS\Core\Console\CommandRegistry;
+use TYPO3\CMS\Core\Core\BootService;
 
 /**
  * ListCommand displays the list of all available commands for the application.
  */
 class ListCommand extends SymfonyListCommand
 {
-    protected CommandRegistry $commandRegistry;
+    protected ContainerInterface $failsafeContainer;
+    protected BootService $bootService;
 
-    public function __construct(CommandRegistry $commandRegistry)
+    public function __construct(ContainerInterface $failsafeContainer, BootService $bootService)
     {
-        $this->commandRegistry = $commandRegistry;
+        $this->failsafeContainer = $failsafeContainer;
+        $this->bootService = $bootService;
         parent::__construct();
     }
 
@@ -42,8 +46,18 @@ class ListCommand extends SymfonyListCommand
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $degraded = false;
+        try {
+            $container = $this->bootService->getContainer();
+        } catch (\Throwable $e) {
+            $container = $this->failsafeContainer;
+            $degraded = true;
+        }
+
+        $commandRegistry = $container->get(CommandRegistry::class);
+
         $helper = new DescriptorHelper();
-        $helper->register('txt', new TextDescriptor($this->commandRegistry));
+        $helper->register('txt', new TextDescriptor($commandRegistry, $degraded));
         $helper->describe($output, $this->getApplication(), [
             'format' => $input->getOption('format'),
             'raw_text' => $input->getOption('raw'),
diff --git a/typo3/sysext/core/Classes/Console/CommandApplication.php b/typo3/sysext/core/Classes/Console/CommandApplication.php
index 3c93507f10b5f56d75fa565a743a91c81816bf35..0a7ea3f43e1036aba98531abe6d4e8bee1a89d58 100644
--- a/typo3/sysext/core/Classes/Console/CommandApplication.php
+++ b/typo3/sysext/core/Classes/Console/CommandApplication.php
@@ -17,15 +17,18 @@ namespace TYPO3\CMS\Core\Console;
 
 use Symfony\Component\Console\Application;
 use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\ExceptionInterface;
 use Symfony\Component\Console\Input\ArgvInput;
 use Symfony\Component\Console\Output\ConsoleOutput;
 use TYPO3\CMS\Core\Authentication\CommandLineUserAuthentication;
+use TYPO3\CMS\Core\Configuration\ConfigurationManager;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\DateTimeAspect;
 use TYPO3\CMS\Core\Context\UserAspect;
 use TYPO3\CMS\Core\Context\VisibilityAspect;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
 use TYPO3\CMS\Core\Core\ApplicationInterface;
+use TYPO3\CMS\Core\Core\BootService;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Information\Typo3Version;
@@ -37,26 +40,27 @@ use TYPO3\CMS\Core\Localization\LanguageService;
  */
 class CommandApplication implements ApplicationInterface
 {
-    /**
-     * @var Context
-     */
-    protected $context;
+    protected Context $context;
 
-    /**
-     * @var CommandRegistry
-     */
-    protected $commandRegistry;
+    protected CommandRegistry $commandRegistry;
 
-    /**
-     * Instance of the symfony application
-     * @var Application
-     */
-    protected $application;
+    protected ConfigurationManager $configurationManager;
 
-    public function __construct(Context $context, CommandRegistry $commandRegistry)
-    {
+    protected BootService $bootService;
+
+    protected Application $application;
+
+    public function __construct(
+        Context $context,
+        CommandRegistry $commandRegistry,
+        ConfigurationManager $configurationMananger,
+        BootService $bootService
+    ) {
         $this->context = $context;
         $this->commandRegistry = $commandRegistry;
+        $this->configurationManager = $configurationMananger;
+        $this->bootService = $bootService;
+
         $this->checkEnvironmentOrDie();
         $this->application = new Application('TYPO3 CMS', sprintf(
             '%s (Application Context: <comment>%s</comment>)',
@@ -76,12 +80,31 @@ class CommandApplication implements ApplicationInterface
      */
     public function run(callable $execute = null)
     {
-        $this->initializeContext();
-
         $input = new ArgvInput();
         $output = new ConsoleOutput();
 
-        Bootstrap::loadExtTables();
+        $commandName = $this->getCommandName($input);
+        if ($this->wantsFullBoot($commandName)) {
+            // Do a full boot if command is not a low-level command
+            $container = $this->bootService->getContainer();
+            $this->application->setCommandLoader($container->get(CommandRegistry::class));
+            $this->context = $container->get(Context::class);
+
+            $isLowLevelCommandShortcut = false;
+            try {
+                $realName = $this->application->find($commandName)->getName();
+                // Do not load ext_localconf if a low level command was found
+                // due to using a shortcut
+                $isLowLevelCommandShortcut = !$this->wantsFullBoot($realName);
+            } catch (ExceptionInterface $e) {
+                // Errors must be ignored, full binding/validation happens later when the console application runs.
+            }
+            if (!$isLowLevelCommandShortcut && $this->essentialConfigurationExists()) {
+                $this->bootService->loadExtLocalconfDatabaseAndExtTables();
+            }
+        }
+
+        $this->initializeContext();
         // create the BE_USER object (not logged in yet)
         Bootstrap::initializeBackendUser(CommandLineUserAuthentication::class);
         $GLOBALS['LANG'] = LanguageService::createFromUserPreferences($GLOBALS['BE_USER']);
@@ -97,6 +120,36 @@ class CommandApplication implements ApplicationInterface
         exit($exitCode);
     }
 
+    protected function wantsFullBoot(string $commandName): bool
+    {
+        if ($commandName === 'help') {
+            return true;
+        }
+        return !$this->commandRegistry->has($commandName);
+    }
+
+    protected function getCommandName(ArgvInput $input): string
+    {
+        try {
+            $input->bind($this->application->getDefinition());
+        } catch (ExceptionInterface $e) {
+            // Errors must be ignored, full binding/validation happens later when the console application runs.
+        }
+
+        return $input->getFirstArgument() ?? 'list';
+    }
+
+    /**
+     * Check if LocalConfiguration.php and PackageStates.php exist
+     *
+     * @return bool TRUE when the essential configuration is available, otherwise FALSE
+     */
+    protected function essentialConfigurationExists(): bool
+    {
+        return file_exists($this->configurationManager->getLocalConfigurationFileLocation())
+            && file_exists(Environment::getLegacyConfigPath() . '/PackageStates.php');
+    }
+
     /**
      * Check the script is called from a cli environment.
      */
diff --git a/typo3/sysext/core/Classes/Core/BootService.php b/typo3/sysext/core/Classes/Core/BootService.php
new file mode 100644
index 0000000000000000000000000000000000000000..2501940781e1d1990f91d37ecfb9f3565db52a23
--- /dev/null
+++ b/typo3/sysext/core/Classes/Core/BootService.php
@@ -0,0 +1,155 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Core;
+
+use Psr\Container\ContainerInterface;
+use Psr\EventDispatcher\EventDispatcherInterface;
+use TYPO3\CMS\Core\DependencyInjection\ContainerBuilder;
+use TYPO3\CMS\Core\Imaging\IconRegistry;
+use TYPO3\CMS\Core\Package\PackageManager;
+use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * @internal This is NOT an API class, it is for internal use in TYPO3 core only.
+ */
+class BootService
+{
+    private ContainerBuilder $containerBuilder;
+
+    private ContainerInterface $failsafeContainer;
+
+    private ?ContainerInterface $container = null;
+
+    public function __construct(ContainerBuilder $containerBuilder, ContainerInterface $failsafeContainer)
+    {
+        $this->containerBuilder = $containerBuilder;
+        $this->failsafeContainer = $failsafeContainer;
+    }
+
+    public function getContainer(bool $allowCaching = true): ContainerInterface
+    {
+        return $this->container ?? $this->prepareContainer($allowCaching);
+    }
+
+    private function prepareContainer(bool $allowCaching = true): ContainerInterface
+    {
+        $packageManager = $this->failsafeContainer->get(PackageManager::class);
+        $dependencyInjectionContainerCache = $this->failsafeContainer->get('cache.di');
+
+        $failsafe = false;
+
+        // Build a non-failsafe container which is required for loading ext_localconf
+        $this->container = $this->containerBuilder->createDependencyInjectionContainer($packageManager, $dependencyInjectionContainerCache, $failsafe);
+        $this->container->set('_early.boot-service', $this);
+        if ($allowCaching) {
+            $this->container->get('boot.state')->cacheDisabled = false;
+            $coreCache = Bootstrap::createCache('core');
+            // Core cache is initialized with a NullBackend in failsafe mode.
+            // Replace it with a new cache that uses the real backend.
+            $this->container->set('_early.cache.core', $coreCache);
+            $this->container->set('_early.cache.assets', Bootstrap::createCache('assets'));
+            $this->container->get(PackageManager::class)->injectCoreCache($coreCache);
+        }
+
+        return $this->container;
+    }
+
+    /**
+     * Switch global context to a new context, or revert
+     * to the original booting container if no container
+     * is specified
+     *
+     * @param ContainerInterface $container
+     * @param array $backup
+     * @return array
+     */
+    public function makeCurrent(ContainerInterface $container = null, array $backup = []): array
+    {
+        $container = $container ?? $backup['container'] ?? $this->failsafeContainer;
+
+        $newBackup = [
+            'singletonInstances' => GeneralUtility::getSingletonInstances(),
+            'container' => GeneralUtility::getContainer(),
+        ];
+
+        GeneralUtility::purgeInstances();
+
+        // Set global state to the non-failsafe container and it's instances
+        GeneralUtility::setContainer($container);
+        ExtensionManagementUtility::setPackageManager($container->get(PackageManager::class));
+
+        $backupSingletonInstances = $backup['singletonInstances'] ?? [];
+        foreach ($backupSingletonInstances as $className => $instance) {
+            GeneralUtility::setSingletonInstance($className, $instance);
+        }
+
+        return $newBackup;
+    }
+
+    /**
+     * Bootstrap a non-failsafe container and load ext_localconf
+     *
+     * Use by actions like the database analyzer and the upgrade wizards which
+     * need additional bootstrap actions performed.
+     *
+     * Those actions can potentially fatal if some old extension is loaded that triggers
+     * a fatal in ext_localconf or ext_tables code! Use only if really needed.
+     *
+     * @param bool $resetContainer
+     * @param bool $allowCaching
+     * @return ContainerInterface
+     */
+    public function loadExtLocalconfDatabaseAndExtTables(bool $resetContainer = false, bool $allowCaching = true): ContainerInterface
+    {
+        $container = $this->getContainer($allowCaching);
+
+        $backup = $this->makeCurrent($container);
+        $beUserBackup = $GLOBALS['BE_USER'] ?? null;
+
+        $container->get('boot.state')->done = false;
+        $assetsCache = $container->get('cache.assets');
+        IconRegistry::setCache($assetsCache);
+        PageRenderer::setCache($assetsCache);
+        $eventDispatcher = $container->get(EventDispatcherInterface::class);
+        ExtensionManagementUtility::setEventDispatcher($eventDispatcher);
+        Bootstrap::loadTypo3LoadedExtAndExtLocalconf($allowCaching, $container->get('cache.core'));
+        Bootstrap::unsetReservedGlobalVariables();
+        $GLOBALS['BE_USER'] = $beUserBackup;
+        $container->get('boot.state')->done = true;
+        Bootstrap::loadBaseTca($allowCaching);
+        Bootstrap::loadExtTables($allowCaching);
+
+        if ($resetContainer) {
+            $this->makeCurrent(null, $backup);
+        }
+
+        return $container;
+    }
+
+    public function resetGlobalContainer(): void
+    {
+        $this->makeCurrent(null, []);
+    }
+
+    public function getFailsafeContainer(): ContainerInterface
+    {
+        return $this->failsafeContainer;
+    }
+}
diff --git a/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php b/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php
index 8df0e0ae494d96c652288e2cd80f966d6d482d08..040f679bce1043c7fc759d57c4ef8169520a5f14 100644
--- a/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php
+++ b/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php
@@ -127,6 +127,9 @@ class ContainerBuilder
             $containerBuilder->setAlias($id, $syntheticId)->setPublic(true);
         }
 
+        // Optional service, set by BootService as back reference to the original bootService
+        $containerBuilder->register('_early.boot-service')->setSynthetic(true)->setPublic(true);
+
         $containerBuilder->compile();
 
         return $containerBuilder;
diff --git a/typo3/sysext/core/Classes/ServiceProvider.php b/typo3/sysext/core/Classes/ServiceProvider.php
index 08fafac75df186b2936afb6b0692a6fd0c7d2ab2..6c8e53c76ff064cda8be878b23c7a5858b1c2142 100644
--- a/typo3/sysext/core/Classes/ServiceProvider.php
+++ b/typo3/sysext/core/Classes/ServiceProvider.php
@@ -23,6 +23,7 @@ use Psr\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\Console\Command\HelpCommand;
 use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as SymfonyEventDispatcherInterface;
 use TYPO3\CMS\Core\Core\Environment;
+use TYPO3\CMS\Core\DependencyInjection\ContainerBuilder;
 use TYPO3\CMS\Core\Package\AbstractServiceProvider;
 use TYPO3\SymfonyPsrEventDispatcherAdapter\EventDispatcherAdapter as SymfonyEventDispatcher;
 
@@ -49,6 +50,7 @@ class ServiceProvider extends AbstractServiceProvider
             Console\CommandApplication::class => [ static::class, 'getConsoleCommandApplication' ],
             Console\CommandRegistry::class => [ static::class, 'getConsoleCommandRegistry' ],
             Context\Context::class => [ static::class, 'getContext' ],
+            Core\BootService::class => [ static::class, 'getBootService' ],
             Crypto\PasswordHashing\PasswordHashFactory::class => [ static::class, 'getPasswordHashFactory' ],
             EventDispatcher\EventDispatcher::class => [ static::class, 'getEventDispatcher' ],
             EventDispatcher\ListenerProvider::class => [ static::class, 'getEventListenerProvider' ],
@@ -137,7 +139,8 @@ class ServiceProvider extends AbstractServiceProvider
     public static function getListCommand(ContainerInterface $container): Command\ListCommand
     {
         return new Command\ListCommand(
-            $container->get(Console\CommandRegistry::class)
+            $container,
+            $container->get(Core\BootService::class)
         );
     }
 
@@ -155,7 +158,9 @@ class ServiceProvider extends AbstractServiceProvider
     {
         return new Console\CommandApplication(
             $container->get(Context\Context::class),
-            $container->get(Console\CommandRegistry::class)
+            $container->get(Console\CommandRegistry::class),
+            $container->get(Configuration\ConfigurationManager::class),
+            $container->get(Core\BootService::class)
         );
     }
 
@@ -193,6 +198,17 @@ class ServiceProvider extends AbstractServiceProvider
         return new Context\Context();
     }
 
+    public static function getBootService(ContainerInterface $container): Core\BootService
+    {
+        if ($container->has('_early.boot-service')) {
+            return $container->get('_early.boot-service');
+        }
+        return new Core\BootService(
+            $container->get(ContainerBuilder::class),
+            $container
+        );
+    }
+
     public static function getPasswordHashFactory(ContainerInterface $container): Crypto\PasswordHashing\PasswordHashFactory
     {
         return new Crypto\PasswordHashing\PasswordHashFactory();
diff --git a/typo3/sysext/core/Resources/Private/Php/cli.php b/typo3/sysext/core/Resources/Private/Php/cli.php
index 7b9b55ee2e6c682596276738f9b8810b46d4b38f..d96be4e832a40e8d31b0381eb0808ee1b95d9b70 100644
--- a/typo3/sysext/core/Resources/Private/Php/cli.php
+++ b/typo3/sysext/core/Resources/Private/Php/cli.php
@@ -20,5 +20,5 @@
 call_user_func(function () {
     $classLoader = require __DIR__ . '/../../../../../../vendor/autoload.php';
     \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(4, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI);
-    \TYPO3\CMS\Core\Core\Bootstrap::init($classLoader)->get(\TYPO3\CMS\Core\Console\CommandApplication::class)->run();
+    \TYPO3\CMS\Core\Core\Bootstrap::init($classLoader, true)->get(\TYPO3\CMS\Core\Console\CommandApplication::class)->run();
 });
diff --git a/typo3/sysext/core/composer.json b/typo3/sysext/core/composer.json
index ae5f12cb3d89bce0bded420f5cf9edfdc329aa27..bee5276c52847385a4f5a3e3543b9e10d77f7e5c 100644
--- a/typo3/sysext/core/composer.json
+++ b/typo3/sysext/core/composer.json
@@ -59,7 +59,7 @@
 		"symfony/routing": "^5.2",
 		"symfony/yaml": "^5.2",
 		"typo3/class-alias-loader": "^1.0",
-		"typo3/cms-cli": "^2.0",
+		"typo3/cms-cli": "^3.0",
 		"typo3/cms-composer-installers": "^2.0 || ^3.0",
 		"typo3/phar-stream-wrapper": "^3.1.6",
 		"typo3/symfony-psr-event-dispatcher-adapter": "^1.0 || ^2.0",
diff --git a/typo3/sysext/install/Classes/Command/UpgradeWizardListCommand.php b/typo3/sysext/install/Classes/Command/UpgradeWizardListCommand.php
index f3e1089accad61da54c6adc6cf0f2d7dcb207072..6bc57dfe62c2f1386e17d498a6253d854292a5db 100644
--- a/typo3/sysext/install/Classes/Command/UpgradeWizardListCommand.php
+++ b/typo3/sysext/install/Classes/Command/UpgradeWizardListCommand.php
@@ -72,7 +72,7 @@ class UpgradeWizardListCommand extends Command
      */
     protected function bootstrap(): void
     {
-        $this->lateBootService->loadExtLocalconfDatabaseAndExtTables();
+        $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
         Bootstrap::initializeBackendUser(CommandLineUserAuthentication::class);
         Bootstrap::initializeBackendAuthentication();
     }
diff --git a/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php b/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php
index 93ceba4d9393d7e193c87ca61fb9ecebbde58bc1..9e6280637dc55ff71abf2fa7de1b08667cf33e3c 100644
--- a/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php
+++ b/typo3/sysext/install/Classes/Command/UpgradeWizardRunCommand.php
@@ -77,7 +77,7 @@ class UpgradeWizardRunCommand extends Command
      */
     protected function bootstrap(): void
     {
-        $this->lateBootService->loadExtLocalconfDatabaseAndExtTables();
+        $this->lateBootService->loadExtLocalconfDatabaseAndExtTables(false);
         Bootstrap::initializeBackendUser(CommandLineUserAuthentication::class);
         Bootstrap::initializeBackendAuthentication();
         $this->upgradeWizardsService->isDatabaseCharsetUtf8() ?: $this->upgradeWizardsService->setDatabaseCharsetUtf8();
diff --git a/typo3/sysext/install/Classes/Service/LateBootService.php b/typo3/sysext/install/Classes/Service/LateBootService.php
index ac779dfa7ff823a2c93a0b7c78834d0e68a1a6fe..dd44754b6f5c6fc1420d04d19fc35c8b7398ce69 100644
--- a/typo3/sysext/install/Classes/Service/LateBootService.php
+++ b/typo3/sysext/install/Classes/Service/LateBootService.php
@@ -18,138 +18,20 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Install\Service;
 
 use Psr\Container\ContainerInterface;
-use Psr\EventDispatcher\EventDispatcherInterface;
-use TYPO3\CMS\Core\Core\Bootstrap;
-use TYPO3\CMS\Core\DependencyInjection\ContainerBuilder;
-use TYPO3\CMS\Core\Imaging\IconRegistry;
-use TYPO3\CMS\Core\Package\PackageManager;
-use TYPO3\CMS\Core\Page\PageRenderer;
-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Core\BootService;
 
 /**
  * @internal This is NOT an API class, it is for internal use in the install tool only.
  */
-class LateBootService
+class LateBootService extends BootService
 {
-    /**
-     * @var ContainerBuilder
-     */
-    private $containerBuilder;
-
-    /**
-     * @var ContainerInterface
-     */
-    private $failsafeContainer;
-
-    /**
-     * @var ContainerInterface
-     */
-    private $container;
-
-    /**
-     * @param ContainerBuilder $containerBuilder
-     * @param ContainerInterface $failsafeContainer
-     */
-    public function __construct(ContainerBuilder $containerBuilder, ContainerInterface $failsafeContainer)
-    {
-        $this->containerBuilder = $containerBuilder;
-        $this->failsafeContainer = $failsafeContainer;
-    }
-
-    /**
-     * @return ContainerInterface
-     */
-    public function getContainer(): ContainerInterface
-    {
-        return $this->container ?? $this->prepareContainer();
-    }
-
-    /**
-     * @return ContainerInterface
-     */
-    private function prepareContainer(): ContainerInterface
-    {
-        $packageManager = $this->failsafeContainer->get(PackageManager::class);
-        $dependencyInjectionContainerCache = $this->failsafeContainer->get('cache.di');
-
-        $failsafe = false;
-
-        // Build a non-failsafe container which is required for loading ext_localconf
-        return $this->container = $this->containerBuilder->createDependencyInjectionContainer($packageManager, $dependencyInjectionContainerCache, $failsafe);
-    }
-
-    /**
-     * Switch global context to a new context, or revert
-     * to the original booting container if no container
-     * is specified
-     *
-     * @param ContainerInterface $container
-     * @param array $backup
-     * @return array
-     */
-    public function makeCurrent(ContainerInterface $container = null, array $backup = []): array
+    public function getContainer(bool $allowCaching = false): ContainerInterface
     {
-        $container = $container ?? $backup['container'] ?? $this->failsafeContainer;
-
-        $newBackup = [
-            'singletonInstances' => GeneralUtility::getSingletonInstances(),
-            'container' => GeneralUtility::getContainer(),
-        ];
-
-        GeneralUtility::purgeInstances();
-
-        // Set global state to the non-failsafe container and it's instances
-        GeneralUtility::setContainer($container);
-        ExtensionManagementUtility::setPackageManager($container->get(PackageManager::class));
-
-        $backupSingletonInstances = $backup['singletonInstances'] ?? [];
-        foreach ($backupSingletonInstances as $className => $instance) {
-            GeneralUtility::setSingletonInstance($className, $instance);
-        }
-
-        return $newBackup;
-    }
-
-    /**
-     * Bootstrap a non-failsafe container and load ext_localconf
-     *
-     * Use by actions like the database analyzer and the upgrade wizards which
-     * need additional bootstrap actions performed.
-     *
-     * Those actions can potentially fatal if some old extension is loaded that triggers
-     * a fatal in ext_localconf or ext_tables code! Use only if really needed.
-     *
-     * @param bool $resetContainer
-     * @return ContainerInterface
-     */
-    public function loadExtLocalconfDatabaseAndExtTables(bool $resetContainer = true): ContainerInterface
-    {
-        $container = $this->getContainer();
-
-        $backup = $this->makeCurrent($container);
-
-        $container->get('boot.state')->done = false;
-        $assetsCache = $container->get('cache.assets');
-        IconRegistry::setCache($assetsCache);
-        PageRenderer::setCache($assetsCache);
-        $eventDispatcher = $container->get(EventDispatcherInterface::class);
-        ExtensionManagementUtility::setEventDispatcher($eventDispatcher);
-        Bootstrap::loadTypo3LoadedExtAndExtLocalconf(false);
-        Bootstrap::unsetReservedGlobalVariables();
-        $container->get('boot.state')->done = true;
-        Bootstrap::loadBaseTca(false);
-        Bootstrap::loadExtTables(false);
-
-        if ($resetContainer) {
-            $this->makeCurrent(null, $backup);
-        }
-
-        return $container;
+        return parent::getContainer($allowCaching);
     }
 
-    public function resetGlobalContainer(): void
+    public function loadExtLocalconfDatabaseAndExtTables(bool $resetContainer = true, bool $allowCaching = false): ContainerInterface
     {
-        $this->makeCurrent(null, []);
+        return parent::loadExtLocalconfDatabaseAndExtTables($resetContainer, $allowCaching);
     }
 }