diff --git a/core/core.services.yml b/core/core.services.yml
index 62a0f3e..7c1e473 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1175,7 +1175,7 @@ services:
     class: Drupal\Core\EventSubscriber\CustomPageExceptionHtmlSubscriber
     tags:
       - { name: event_subscriber }
-    arguments: ['@config.factory', '@http_kernel', '@logger.channel.php', '@redirect.destination', '@router.no_access_checks']
+    arguments: ['@config.factory', '@http_kernel', '@logger.channel.php', '@redirect.destination', '@router.no_access_checks', '@access_manager']
   exception.fast_404_html:
     class: Drupal\Core\EventSubscriber\Fast404ExceptionHtmlSubscriber
     tags:
diff --git a/core/lib/Drupal/Core/Access/AccessManagerInterface.php b/core/lib/Drupal/Core/Access/AccessManagerInterface.php
index 7749ef2..409e3b2 100644
--- a/core/lib/Drupal/Core/Access/AccessManagerInterface.php
+++ b/core/lib/Drupal/Core/Access/AccessManagerInterface.php
@@ -83,6 +83,6 @@ public function checkRequest(Request $request, AccountInterface $account = NULL,
    *   returned, i.e. TRUE means access is explicitly allowed, FALSE means
    *   access is either explicitly forbidden or "no opinion".
    */
-  public function check(RouteMatchInterface $route_match, AccountInterface $account = NULL, Request $request = NULL, $return_as_object = FALSE);
+  public function   check(RouteMatchInterface $route_match, AccountInterface $account = NULL, Request $request = NULL, $return_as_object = FALSE);
 
 }
diff --git a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
index ce56970..ce428a6 100644
--- a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
@@ -7,8 +7,10 @@
 
 namespace Drupal\Core\EventSubscriber;
 
+use Drupal\Core\Access\AccessManagerInterface;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Routing\RedirectDestinationInterface;
+use Drupal\Core\Url;
 use Psr\Log\LoggerInterface;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
@@ -28,6 +30,13 @@ class CustomPageExceptionHtmlSubscriber extends DefaultExceptionHtmlSubscriber {
   protected $configFactory;
 
   /**
+   * The access manager.
+   *
+   * @var \Drupal\Core\Access\AccessManagerInterface
+   */
+  protected $accessManager;
+
+  /**
    * Constructs a new CustomPageExceptionHtmlSubscriber.
    *
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
@@ -41,9 +50,10 @@ class CustomPageExceptionHtmlSubscriber extends DefaultExceptionHtmlSubscriber {
    * @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $access_unaware_router
    *   A router implementation which does not check access.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, HttpKernelInterface $http_kernel, LoggerInterface $logger, RedirectDestinationInterface $redirect_destination, UrlMatcherInterface $access_unaware_router) {
+  public function __construct(ConfigFactoryInterface $config_factory, HttpKernelInterface $http_kernel, LoggerInterface $logger, RedirectDestinationInterface $redirect_destination, UrlMatcherInterface $access_unaware_router, AccessManagerInterface $access_manager) {
     parent::__construct($http_kernel, $logger, $redirect_destination, $access_unaware_router);
     $this->configFactory = $config_factory;
+    $this->accessManager = $access_manager;
   }
 
   /**
@@ -59,7 +69,10 @@ protected static function getPriority() {
   public function on403(GetResponseForExceptionEvent $event) {
     $custom_403_path = $this->configFactory->get('system.site')->get('page.403');
     if (!empty($custom_403_path)) {
-      $this->makeSubrequest($event, $custom_403_path, Response::HTTP_FORBIDDEN);
+      $url = Url::fromUserInput($custom_403_path);
+      if ($url->isRouted() && $this->accessManager->checkNamedRoute($url->getRouteName(), $url->getRouteParameters())) {
+        $this->makeSubrequest($event, $custom_403_path, Response::HTTP_FORBIDDEN);
+      }
     }
   }
 
diff --git a/core/modules/system/src/Tests/System/AccessDeniedTest.php b/core/modules/system/src/Tests/System/AccessDeniedTest.php
index 5c6c3bf..f3cc0e0 100644
--- a/core/modules/system/src/Tests/System/AccessDeniedTest.php
+++ b/core/modules/system/src/Tests/System/AccessDeniedTest.php
@@ -23,7 +23,7 @@ class AccessDeniedTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = ['block'];
+  public static $modules = ['block', 'node'];
 
   protected $adminUser;
 
@@ -109,4 +109,14 @@ function testAccessDenied() {
     // Check that we're still on the same page.
     $this->assertText(t('Basic site settings'));
   }
+
+  public function testAccessDeniedCustomPageWithAccessDenied() {
+    // Sets up a 404 page not accessible by the anonymous user.
+    $this->config('system.site')->set('page.403', '/admin/index')->save();
+
+    $this->drupalGet('/admin');
+    $this->assertNoText('Administration');
+    $this->assertResponse(403);
+  }
+
 }
diff --git a/core/modules/system/src/Tests/System/PageNotFoundTest.php b/core/modules/system/src/Tests/System/PageNotFoundTest.php
index b7c0609..2632d7d 100644
--- a/core/modules/system/src/Tests/System/PageNotFoundTest.php
+++ b/core/modules/system/src/Tests/System/PageNotFoundTest.php
@@ -50,4 +50,14 @@ function testPageNotFound() {
     $this->drupalGet($this->randomMachineName(10));
     $this->assertText($this->adminUser->getUsername(), 'Found the custom 404 page');
   }
+
+  public function testAccessDeniedCustomPageWithAccessDenied() {
+    // Sets up a 404 page not accessible by the anonymous user.
+    $this->config('system.site')->set('page.404', '/admin/index')->save();
+
+    $this->drupalGet('/admin');
+    $this->assertNoText('Administration');
+    $this->assertResponse(403);
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php
index cdcf5b4..caf8131 100644
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php
@@ -70,6 +70,13 @@ class CustomPageExceptionHtmlSubscriberTest extends UnitTestCase {
   protected $accessUnawareRouter;
 
   /**
+   * The access manager.
+   *
+   * @var \Drupal\Core\Access\AccessManagerInterface
+   */
+  protected $accessManager;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -87,8 +94,9 @@ protected function setUp() {
       ->willReturn([
         '_controller' => 'mocked',
       ]);
+    $this->accessManager = $this->getMock('Drupal\Core\Access\AccessManagerInterface');
 
-    $this->customPageSubscriber = new CustomPageExceptionHtmlSubscriber($this->configFactory, $this->kernel, $this->logger, $this->redirectDestination, $this->accessUnawareRouter);
+    $this->customPageSubscriber = new CustomPageExceptionHtmlSubscriber($this->configFactory, $this->kernel, $this->logger, $this->redirectDestination, $this->accessUnawareRouter, $this->accessManager);
 
     // You can't create an exception in PHP without throwing it. Store the
     // current error_log, and disable it temporarily.
