diff --git a/typo3/sysext/backend/Classes/Controller/BackendController.php b/typo3/sysext/backend/Classes/Controller/BackendController.php
index d829808b2bc250de17f73609a24170b791245b8f..8d352b8b534b5cec7451324c77032df5edcec67d 100644
--- a/typo3/sysext/backend/Classes/Controller/BackendController.php
+++ b/typo3/sysext/backend/Classes/Controller/BackendController.php
@@ -39,8 +39,12 @@ use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
 use TYPO3\CMS\Core\Http\JsonResponse;
 use TYPO3\CMS\Core\Information\Typo3Version;
 use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
 use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
 use TYPO3\CMS\Core\Type\File\ImageInfo;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
@@ -70,6 +74,7 @@ class BackendController
         protected readonly ExtensionConfiguration $extensionConfiguration,
         protected readonly BackendViewFactory $viewFactory,
         protected readonly EventDispatcherInterface $eventDispatcher,
+        protected readonly FlashMessageService $flashMessageService,
     ) {
         $this->modules = $this->moduleProvider->getModulesForModuleMenu($this->getBackendUser());
     }
@@ -248,6 +253,8 @@ class BackendController
     protected function getStartupModule(ServerRequestInterface $request): array
     {
         $startModule = null;
+        $startModuleIdentifier = null;
+        $inaccessibleRedirectModule = null;
         $moduleParameters = [];
         try {
             $redirect = RouteRedirect::createFromRequest($request);
@@ -257,29 +264,33 @@ class BackendController
                 if ($this->moduleProvider->accessGranted($redirect->getName(), $this->getBackendUser())) {
                     // Only add start module from request in case user has access.
                     // Access might temporarily be blocked due to being in a workspace.
-                    $startModule = $redirect->getName();
+                    $startModuleIdentifier = $redirect->getName();
                     $moduleParameters = $redirect->getParameters();
+                } elseif ($this->moduleProvider->isModuleRegistered($redirect->getName())) {
+                    // A redirect is set, however, the user is not allowed to access the module.
+                    // Store the requested module to later inform the user about the forced redirect.
+                    $inaccessibleRedirectModule = $this->moduleProvider->getModule($redirect->getName());
                 }
             }
         } finally {
             // No valid redirect, check for the start module
-            if (!$startModule) {
+            if (!$startModuleIdentifier) {
                 $backendUser = $this->getBackendUser();
                 // start module on first login, will be removed once used the first time
                 if (isset($backendUser->uc['startModuleOnFirstLogin'])) {
-                    $startModule = $backendUser->uc['startModuleOnFirstLogin'];
+                    $startModuleIdentifier = $backendUser->uc['startModuleOnFirstLogin'];
                     unset($backendUser->uc['startModuleOnFirstLogin']);
                     $backendUser->writeUC();
                 } elseif (isset($backendUser->uc['startModule']) && $this->moduleProvider->accessGranted($backendUser->uc['startModule'], $backendUser)) {
-                    $startModule = $backendUser->uc['startModule'];
+                    $startModuleIdentifier = $backendUser->uc['startModule'];
                 } elseif ($firstAccessibleModule = $this->moduleProvider->getFirstAccessibleModule($backendUser)) {
-                    $startModule = $firstAccessibleModule->getIdentifier();
+                    $startModuleIdentifier = $firstAccessibleModule->getIdentifier();
                 }
 
                 // check if the start module has additional parameters, so a redirect to a specific
                 // action is possible
-                if (is_string($startModule) && str_contains($startModule, '->')) {
-                    [$startModule, $startModuleParameters] = explode('->', $startModule, 2);
+                if (is_string($startModuleIdentifier) && str_contains($startModuleIdentifier, '->')) {
+                    [$startModuleIdentifier, $startModuleParameters] = explode('->', $startModuleIdentifier, 2);
                     // if no GET parameters are set, check if there are parameters given from the UC
                     if (!$moduleParameters && $startModuleParameters) {
                         $moduleParameters = $startModuleParameters;
@@ -287,10 +298,11 @@ class BackendController
                 }
             }
         }
-        if ($startModule) {
-            if ($this->moduleProvider->isModuleRegistered($startModule)) {
-                // startModule may be an alias, resolve original module name
-                $startModule = $this->moduleProvider->getModule($startModule, $this->getBackendUser())?->getIdentifier();
+        if ($startModuleIdentifier) {
+            if ($this->moduleProvider->isModuleRegistered($startModuleIdentifier)) {
+                // startModuleIdentifier may be an alias, resolve original module
+                $startModule = $this->moduleProvider->getModule($startModuleIdentifier, $this->getBackendUser());
+                $startModuleIdentifier = $startModule?->getIdentifier();
             }
             if (is_array($moduleParameters)) {
                 $parameters = $moduleParameters;
@@ -299,8 +311,11 @@ class BackendController
                 parse_str($moduleParameters, $parameters);
             }
             try {
-                $deepLink = $this->uriBuilder->buildUriFromRoute($startModule, $parameters);
-                return [$startModule, (string)$deepLink];
+                $deepLink = $this->uriBuilder->buildUriFromRoute($startModuleIdentifier, $parameters);
+                if ($startModule !== null && $inaccessibleRedirectModule !== null) {
+                    $this->enqueueRedirectMessage($startModule, $inaccessibleRedirectModule);
+                }
+                return [$startModuleIdentifier, (string)$deepLink];
             } catch (RouteNotFoundException $e) {
                 // It might be, that the user does not have access to the
                 // $startModule, e.g. for modules with workspace restrictions.
@@ -337,6 +352,25 @@ class BackendController
         return $collapseState === true || $collapseState === 'true';
     }
 
+    protected function enqueueRedirectMessage(ModuleInterface $requestedModule, ModuleInterface $redirectedModule): void
+    {
+        $languageService = $this->getLanguageService();
+        $this->flashMessageService
+            ->getMessageQueueByIdentifier(FlashMessageQueue::NOTIFICATION_QUEUE)
+            ->enqueue(
+                new FlashMessage(
+                    sprintf(
+                        $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:module.noAccess.message'),
+                        $languageService->sL($redirectedModule->getTitle()),
+                        $languageService->sL($requestedModule->getTitle())
+                    ),
+                    $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:module.noAccess.title'),
+                    ContextualFeedbackSeverity::INFO,
+                    true
+                )
+            );
+    }
+
     protected function getBackendUser(): BackendUserAuthentication
     {
         return $GLOBALS['BE_USER'];
diff --git a/typo3/sysext/backend/Classes/Middleware/BackendModuleValidator.php b/typo3/sysext/backend/Classes/Middleware/BackendModuleValidator.php
index a1333e1ed8e7aa305616be57ff4f0e7718fc040e..c7d3feaeecc3d5999fcb9389c50fc40333e92583 100644
--- a/typo3/sysext/backend/Classes/Middleware/BackendModuleValidator.php
+++ b/typo3/sysext/backend/Classes/Middleware/BackendModuleValidator.php
@@ -31,7 +31,12 @@ use TYPO3\CMS\Backend\Routing\RouteRedirect;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Http\RedirectResponse;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Type\Bitmask\Permission;
+use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
 use TYPO3\CMS\Core\Utility\MathUtility;
 
 /**
@@ -44,7 +49,8 @@ class BackendModuleValidator implements MiddlewareInterface
 {
     public function __construct(
         protected readonly UriBuilder $uriBuilder,
-        protected readonly ModuleProvider $moduleProvider
+        protected readonly ModuleProvider $moduleProvider,
+        protected readonly FlashMessageService $flashMessageService,
     ) {}
 
     /**
@@ -55,6 +61,8 @@ class BackendModuleValidator implements MiddlewareInterface
     {
         /** @var Route $route */
         $route = $request->getAttribute('route');
+        $selectedSubModule = null;
+        $inaccessibleSubModule = null;
         $ensureToPersistUserSettings = false;
         $backendUser = $GLOBALS['BE_USER'] ?? null;
         if (!$backendUser
@@ -68,17 +76,21 @@ class BackendModuleValidator implements MiddlewareInterface
         // (either the last used or the first in the list) and store this selection for the user.
         /** @var $module ModuleInterface */
         if ($module->getParentModule() && $module->hasSubModules()) {
-            $selectedSubModule = null;
             // Note: "action" is a special setting, which is evaluated here individually
             $subModuleIdentifier = (string)($backendUser->getModuleData($module->getIdentifier())['action'] ?? '');
-            if ($module->hasSubModule($subModuleIdentifier)
-                && $this->moduleProvider->accessGranted($subModuleIdentifier, $backendUser)
-            ) {
-                // Use the selected sub module if user has access to it. By checking access here,
-                // we prevent that the user can no longer access the parent module, since it would
-                // always run into the ModuleAccessDeniedException.
-                $selectedSubModule = $module->getSubModule($subModuleIdentifier);
-            } else {
+            if ($module->hasSubModule($subModuleIdentifier)) {
+                if ($this->moduleProvider->accessGranted($subModuleIdentifier, $backendUser)) {
+                    // Use the selected sub module if user has access to it. By checking access here,
+                    // we prevent that the user can no longer access the parent module, since it would
+                    // always run into the ModuleAccessDeniedException.
+                    $selectedSubModule = $module->getSubModule($subModuleIdentifier);
+                } else {
+                    // Stored sub module exists but is currently not accessible. Store the
+                    // requested module to later inform the user about the forced redirect.
+                    $inaccessibleSubModule = $module->getSubModule($subModuleIdentifier);
+                }
+            }
+            if ($selectedSubModule === null) {
                 // Try to fetch the first accessible sub module. We check access here to prevent
                 // that the user can no longer access the parent module, since it would always run
                 // into the ModuleAccessDeniedException.
@@ -112,11 +124,15 @@ class BackendModuleValidator implements MiddlewareInterface
         // Validate the requested module
         try {
             $this->validateModuleAccess($request, $module);
+            if ($selectedSubModule !== null && $inaccessibleSubModule !== null) {
+                $this->enqueueRedirectMessage($inaccessibleSubModule, $selectedSubModule);
+            }
         } catch (ModuleAccessDeniedException $e) {
             // Since the user might request a module which is just temporarily blocked, e.g. due to workspace
             // restrictions, do not throw an exception but redirect to the first accessible module - if any.
-            if (($module = $this->moduleProvider->getFirstAccessibleModule($backendUser)) !== null) {
-                return new RedirectResponse($this->uriBuilder->buildUriFromRoute($module->getIdentifier()));
+            if (($firstAccessibleModule = $this->moduleProvider->getFirstAccessibleModule($backendUser)) !== null) {
+                $this->enqueueRedirectMessage($module, $firstAccessibleModule);
+                return new RedirectResponse($this->uriBuilder->buildUriFromRoute($firstAccessibleModule->getIdentifier()));
             }
             // User does not have access to any module.. ¯\_(ツ)_/¯
             throw new NoAccessibleModuleException('You don\'t have access to any module.', 1702480600);
@@ -213,4 +229,28 @@ class BackendModuleValidator implements MiddlewareInterface
             }
         }
     }
+
+    protected function enqueueRedirectMessage(ModuleInterface $requestedModule, ModuleInterface $redirectedModule): void
+    {
+        $languageService = $this->getLanguageService();
+        $this->flashMessageService
+            ->getMessageQueueByIdentifier(FlashMessageQueue::NOTIFICATION_QUEUE)
+            ->enqueue(
+                new FlashMessage(
+                    sprintf(
+                        $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:module.noAccess.message'),
+                        $languageService->sL($redirectedModule->getTitle()),
+                        $languageService->sL($requestedModule->getTitle())
+                    ),
+                    $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:module.noAccess.title'),
+                    ContextualFeedbackSeverity::INFO,
+                    true
+                )
+            );
+    }
+
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
 }
diff --git a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf
index 2227533bd36815439e952533bb2fe93b1406ef13..0653b2837e30eff42c56c00e77f6927699329252 100644
--- a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf
+++ b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf
@@ -142,6 +142,12 @@ Have a nice day.</source>
 			<trans-unit id="modulemenu.label" resname="modulemenu.label">
 				<source>Module Menu</source>
 			</trans-unit>
+			<trans-unit id="module.noAccess.title" resname="module.noAccess.title">
+				<source>No module access</source>
+			</trans-unit>
+			<trans-unit id="module.noAccess.message" resname="module.noAccess.message">
+				<source>You've been redirected to the "%s" module, because you currently can't access the "%s" module. You either don't have the necessary permissions or access is temporarily not possible, e.g. due to workspace restrictions.</source>
+			</trans-unit>
 			<trans-unit id="clearcache.title" resname="clearcache.title">
 				<source>Page cache</source>
 			</trans-unit>
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php
index 2e84f502ee6ce0d60b72334d1f2c589163a445e6..ac32022e14a55fd99440804c21b5803a4aa47ca3 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php
@@ -25,11 +25,17 @@ use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
 use TYPO3\CMS\Core\Http\ServerRequest;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class BackendControllerTest extends FunctionalTestCase
 {
+    protected array $testExtensionsToLoad = ['workspaces'];
+
     public function setUp(): void
     {
         parent::setUp();
@@ -71,4 +77,29 @@ final class BackendControllerTest extends FunctionalTestCase
 
         self::assertInstanceOf(AfterBackendPageRenderEvent::class, $state['after-backend-page-render-listener']);
     }
+
+    /**
+     * @test
+     */
+    public function flashMessageIsDispatchedForForcedRedirect(): void
+    {
+        // Set workspace to disable the site configuration module
+        $GLOBALS['BE_USER']->workspace = 1;
+
+        $request = (new ServerRequest('https://example.com/typo3/main'))
+            ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE)
+            ->withQueryParams(['redirect' => 'site_configuration'])
+            ->withAttribute('route', new Route('/main', ['packageName' => 'typo3/cms-backend', '_identifier' => 'main']));
+
+        $GLOBALS['TYPO3_REQUEST'] = $request;
+        $this->get(BackendController::class)->mainAction($request);
+
+        $flashMessage = $this->get(FlashMessageService::class)
+            ->getMessageQueueByIdentifier(FlashMessageQueue::NOTIFICATION_QUEUE)
+            ->getAllMessages()[0] ?? null;
+
+        self::assertInstanceOf(FlashMessage::class, $flashMessage);
+        self::assertEquals('No module access', $flashMessage->getTitle());
+        self::assertEquals(ContextualFeedbackSeverity::INFO, $flashMessage->getSeverity());
+    }
 }
diff --git a/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php b/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
index ffced0a217486654e4a1ebbdfd24897518a1e91d..1ec5aa66da363c4ef7dbdb00d4410c744e6c42c7 100644
--- a/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
@@ -29,6 +29,10 @@ use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Http\Response;
 use TYPO3\CMS\Core\Http\ServerRequest;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class BackendModuleValidatorTest extends FunctionalTestCase
@@ -48,6 +52,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         $this->subject = new BackendModuleValidator(
             $this->get(UriBuilder::class),
             $this->get(ModuleProvider::class),
+            $this->get(FlashMessageService::class),
         );
         $this->request = new ServerRequest('/some/uri');
         $this->requestHandler = new class () implements RequestHandlerInterface {
@@ -145,6 +150,33 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         );
     }
 
+    /**
+     * @test
+     */
+    public function flashMessageIsDispatchedForForcedRedirect(): void
+    {
+        $module = $this->get(ModuleFactory::class)->createModule(
+            'some_module',
+            [
+                'packageName' => 'typo3/cms-testing',
+                'path' => '/some/module',
+            ]
+        );
+
+        $this->subject->process(
+            $this->request->withAttribute('route', new Route('/some/route', ['module' => $module])),
+            $this->requestHandler
+        );
+
+        $flashMessage = $this->get(FlashMessageService::class)
+            ->getMessageQueueByIdentifier(FlashMessageQueue::NOTIFICATION_QUEUE)
+            ->getAllMessages()[0] ?? null;
+
+        self::assertInstanceOf(FlashMessage::class, $flashMessage);
+        self::assertEquals('No module access', $flashMessage->getTitle());
+        self::assertEquals(ContextualFeedbackSeverity::INFO, $flashMessage->getSeverity());
+    }
+
     /**
      * @test
      */