diff --git a/core/core.services.yml b/core/core.services.yml
index 5d01d87667..9a137b1654 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1220,7 +1220,7 @@ services:
     class: Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber
     tags:
       - { name: event_subscriber }
-    arguments: ['@current_user']
+    arguments: ['@current_user', '@messenger']
   ajax_response.attachments_processor:
     class: Drupal\Core\Ajax\AjaxResponseAttachmentsProcessor
     tags:
diff --git a/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php b/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php
index fad6538fd9..10b7671bef 100644
--- a/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php
+++ b/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php
@@ -8,6 +8,7 @@
 use Drupal\big_pipe_test\BigPipePlaceholderTestCases;
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Logger\RfcLogLevel;
 use Drupal\Core\Url;
@@ -94,7 +95,7 @@ public function testNoJsDetection() {
     $this->drupalLogin($this->rootUser);
     $this->assertSessionCookieExists(TRUE);
     $this->assertBigPipeNoJsCookieExists(FALSE);
-    $this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . base_path() . 'user/1" />' . "\n" . '</noscript>');
+    $this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . UrlHelper::encodePath(base_path() . 'user/1?check_logged_in=1') . '" />' . "\n" . '</noscript>');
     $this->assertNoRaw($no_js_to_js_markup);
     $this->assertBigPipeNoJsMetaRefreshRedirect();
     $this->assertBigPipeNoJsCookieExists(TRUE);
diff --git a/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php b/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php
index cdfebd96be..9f4f3dc999 100644
--- a/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php
+++ b/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php
@@ -159,7 +159,12 @@ protected function loginHttp(AccountInterface $account) {
 
     // Follow the location header.
     $path = $this->getPathFromLocationHeader($response, FALSE);
-    $this->drupalGet($this->httpUrl($path));
+    $parsed_path = parse_url($path);
+    $query = [];
+    if (isset($parsed_path['query'])) {
+      parse_str($parsed_path['query'], $query);
+    }
+    $this->drupalGet($this->httpUrl($parsed_path['path']), ['query' => $query]);
     $this->assertSession()->statusCodeEquals(200);
   }
 
@@ -205,7 +210,12 @@ protected function loginHttps(AccountInterface $account) {
 
     // Follow the location header.
     $path = $this->getPathFromLocationHeader($response, TRUE);
-    $this->drupalGet($this->httpsUrl($path));
+    $parsed_path = parse_url($path);
+    $query = [];
+    if (isset($parsed_path['query'])) {
+      parse_str($parsed_path['query'], $query);
+    }
+    $this->drupalGet($this->httpsUrl($parsed_path['path']), ['query' => $query]);
     $this->assertSession()->statusCodeEquals(200);
   }
 
diff --git a/core/modules/user/src/Authentication/Provider/Cookie.php b/core/modules/user/src/Authentication/Provider/Cookie.php
index ebcdae7517..267cbfe749 100644
--- a/core/modules/user/src/Authentication/Provider/Cookie.php
+++ b/core/modules/user/src/Authentication/Provider/Cookie.php
@@ -2,18 +2,27 @@
 
 namespace Drupal\user\Authentication\Provider;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Authentication\AuthenticationProviderInterface;
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Session\UserSession;
 use Drupal\Core\Session\SessionConfigurationInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Session\SessionInterface;
+use Symfony\Component\HttpKernel\Event\ResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
 
 /**
  * Cookie based authentication provider.
  */
-class Cookie implements AuthenticationProviderInterface {
+class Cookie implements AuthenticationProviderInterface, EventSubscriberInterface {
+
+  use StringTranslationTrait;
 
   /**
    * The session configuration.
@@ -29,6 +38,13 @@ class Cookie implements AuthenticationProviderInterface {
    */
   protected $connection;
 
+  /**
+   * The messenger.
+   *
+   * @var \Drupal\Core\Messenger\MessengerInterface
+   */
+  protected $messenger;
+
   /**
    * Constructs a new cookie authentication provider.
    *
@@ -36,17 +52,25 @@ class Cookie implements AuthenticationProviderInterface {
    *   The session configuration.
    * @param \Drupal\Core\Database\Connection $connection
    *   The database connection.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
    */
-  public function __construct(SessionConfigurationInterface $session_configuration, Connection $connection) {
+  public function __construct(SessionConfigurationInterface $session_configuration, Connection $connection, MessengerInterface $messenger) {
     $this->sessionConfiguration = $session_configuration;
     $this->connection = $connection;
+    $this->messenger = $messenger;
   }
 
   /**
    * {@inheritdoc}
    */
   public function applies(Request $request) {
-    return $request->hasSession() && $this->sessionConfiguration->hasSession($request);
+    $applies = $request->hasSession() && $this->sessionConfiguration->hasSession($request);
+    if (!$applies && $request->query->has('check_logged_in')) {
+      $domain = ltrim(ini_get('session.cookie_domain'), '.') ?: $request->getHttpHost();
+      $this->messenger->addMessage($this->t('To log in to this site, your browser must accept cookies from the domain %domain.', ['%domain' => $domain]), 'error');
+    }
+    return $applies;
   }
 
   /**
@@ -90,4 +114,38 @@ protected function getUserFromSession(SessionInterface $session) {
     return NULL;
   }
 
+  /**
+   * Adds a query parameter to check successful log in redirect URL.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event
+   *   The Event to process.
+   */
+  public function addCheckToUrl(ResponseEvent $event) {
+    $response = $event->getResponse();
+    if ($response instanceof RedirectResponse && $event->getRequest()->hasSession()) {
+      if ($event->getRequest()->getSession()->has('check_logged_in')) {
+        $event->getRequest()->getSession()->remove('check_logged_in');
+        $url = $response->getTargetUrl();
+        $options = UrlHelper::parse($url);
+        $options['query']['check_logged_in'] = '1';
+        $url = $options['path'] . '?' . UrlHelper::buildQuery($options['query']);
+        if (!empty($options['#fragment'])) {
+          $url .= '#' . $options['#fragment'];
+        }
+        $response->setTargetUrl($url);
+      }
+    }
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::RESPONSE][] = ['addCheckToUrl', -1000];
+    return $events;
+  }
+
 }
diff --git a/core/modules/user/tests/src/Functional/UserLoginTest.php b/core/modules/user/tests/src/Functional/UserLoginTest.php
index bbd0e43673..4374b6f15c 100644
--- a/core/modules/user/tests/src/Functional/UserLoginTest.php
+++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
@@ -152,6 +152,37 @@ public function testPasswordRehashOnLogin() {
     $this->assertTrue($password_hasher->check($password, $account->getPassword()));
   }
 
+  /**
+   * Tests with a browser that denies cookies.
+   */
+  public function testCookiesNotAccepted() {
+    $this->drupalGet('user/login');
+    $form_build_id = $this->getSession()->getPage()->findField('form_build_id');
+
+    $account = $this->drupalCreateUser([]);
+    $post = [
+      'form_id' => 'user_login_form',
+      'form_build_id' => $form_build_id,
+      'name' => $account->getAccountName(),
+      'pass' => $account->passRaw,
+      'op' => 'Log in',
+    ];
+    $url = $this->buildUrl(Url::fromRoute('user.login'));
+
+    /** @var \Psr\Http\Message\ResponseInterface $response */
+    $response = $this->getHttpClient()->post($url, [
+      'form_params' => $post,
+      'http_errors' => FALSE,
+      'cookies' => FALSE,
+      'allow_redirects' => FALSE,
+    ]);
+
+    // Follow the location header.
+    $this->drupalGet($response->getHeader('location')[0]);
+    $this->assertSession()->statusCodeEquals(403);
+    $this->assertSession()->pageTextContains('To log in to this site, your browser must accept cookies from the domain');
+  }
+
   /**
    * Make an unsuccessful login attempt.
    *
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 383c093878..a5da54039b 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -445,6 +445,7 @@ function template_preprocess_username(&$variables) {
  *   The account to log in.
  *
  * @see hook_user_login()
+ * @see \Drupal\user\Authentication\Provider\Cookie
  */
 function user_login_finalize(UserInterface $account) {
   \Drupal::currentUser()->setAccount($account);
@@ -462,6 +463,7 @@ function user_login_finalize(UserInterface $account) {
   // in place.
   \Drupal::service('session')->migrate();
   \Drupal::service('session')->set('uid', $account->id());
+  \Drupal::service('session')->set('check_logged_in', TRUE);
   \Drupal::moduleHandler()->invokeAll('user_login', [$account]);
 }
 
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index f79e286a54..f8f7d15f4e 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -17,9 +17,10 @@ services:
       - { name: access_check, applies_to: _user_is_logged_in }
   user.authentication.cookie:
     class: Drupal\user\Authentication\Provider\Cookie
-    arguments: ['@session_configuration', '@database']
+    arguments: ['@session_configuration', '@database', '@messenger']
     tags:
       - { name: authentication_provider, provider_id: 'cookie', priority: 0, global: TRUE }
+      - { name: event_subscriber }
   user.data:
     class: Drupal\user\UserData
     arguments: ['@database']
