diff --git a/core/lib/Drupal/Core/Session/AccountInterface.php b/core/lib/Drupal/Core/Session/AccountInterface.php
index 084943b..ede2854 100644
--- a/core/lib/Drupal/Core/Session/AccountInterface.php
+++ b/core/lib/Drupal/Core/Session/AccountInterface.php
@@ -90,28 +90,34 @@ public function isAnonymous();
   /**
    * Returns the preferred language code of the account.
    *
-   * @param string $default
-   *   (optional) Default language code to return if the account
-   *   has no valid language, defaults to the site default language.
+   * @param bool $fallback_to_default
+   *   (optional) Whether the return value will fall back to the site default
+   *   language if the user has no language preference.
    *
    * @return string
-   *   The language code that is preferred by the account.
+   *   The language code that is preferred by the account. If the preferred
+   *   language is not set or is a language not configured anymore on the site,
+   *   the site default is returned or an empty string is returned (if
+   *   $fallback_to_default is FALSE).
    */
-  public function getPreferredLangcode($default = NULL);
+  public function getPreferredLangcode($fallback_to_default = TRUE);
 
   /**
    * Returns the preferred administrative language code of the account.
    *
    * Defines which language is used on administrative pages.
    *
-   * @param string $default
-   *   (optional) Default language code to return if the account
-   *   has no valid language, defaults to the site default language.
+   * @param bool $fallback_to_default
+   *   (optional) Whether the return value will fall back to the site default
+   *   language if the user has no administration language preference.
    *
    * @return string
-   *   The language code that is preferred by the account.
+   *   The language code that is preferred by the account for administration
+   *   pages. If the preferred language is not set or is a language not
+   *   configured anymore on the site, the site default is returned or an empty
+   *   string is returned (if $fallback_to_default is FALSE).
    */
-  public function getPreferredAdminLangcode($default = NULL);
+  public function getPreferredAdminLangcode($fallback_to_default = TRUE);
 
   /**
    * Returns the username of this account.
diff --git a/core/lib/Drupal/Core/Session/AccountProxy.php b/core/lib/Drupal/Core/Session/AccountProxy.php
index 56a42fa..89e9146 100644
--- a/core/lib/Drupal/Core/Session/AccountProxy.php
+++ b/core/lib/Drupal/Core/Session/AccountProxy.php
@@ -147,15 +147,15 @@ public function isAnonymous() {
   /**
    * {@inheritdoc}
    */
-  public function getPreferredLangcode($default = NULL) {
-    return $this->getAccount()->getPreferredLangcode($default);
+  public function getPreferredLangcode($fallback_to_default = TRUE) {
+    return $this->getAccount()->getPreferredLangcode($fallback_to_default);
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getPreferredAdminLangcode($default = NULL) {
-    return $this->getAccount()->getPreferredAdminLangcode($default);
+  public function getPreferredAdminLangcode($fallback_to_default = TRUE) {
+    return $this->getAccount()->getPreferredAdminLangcode($fallback_to_default);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Session/UserSession.php b/core/lib/Drupal/Core/Session/UserSession.php
index 912d755..7364da9 100644
--- a/core/lib/Drupal/Core/Session/UserSession.php
+++ b/core/lib/Drupal/Core/Session/UserSession.php
@@ -182,26 +182,26 @@ public function isAnonymous() {
   /**
    * {@inheritdoc}
    */
-  function getPreferredLangcode($default = NULL) {
+  function getPreferredLangcode($fallback_to_default = TRUE) {
     $language_list = language_list();
     if (!empty($this->preferred_langcode) && isset($language_list[$this->preferred_langcode])) {
       return $language_list[$this->preferred_langcode]->id;
     }
     else {
-      return $default ? $default : language_default()->id;
+      return $fallback_to_default ? language_default()->id : '';
     }
   }
 
   /**
    * {@inheritdoc}
    */
-  function getPreferredAdminLangcode($default = NULL) {
+  function getPreferredAdminLangcode($fallback_to_default = TRUE) {
     $language_list = language_list();
     if (!empty($this->preferred_admin_langcode) && isset($language_list[$this->preferred_admin_langcode])) {
       return $language_list[$this->preferred_admin_langcode]->id;
     }
     else {
-      return $default ? $default : language_default()->id;
+      return $fallback_to_default ? language_default()->id : '';
     }
   }
 
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index 4074db4..c9451a6 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -248,7 +248,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     $user_preferred_langcode = $register ? $language_interface->id : $account->getPreferredLangcode();
 
-    $user_preferred_admin_langcode = $register ? $language_interface->id : $account->getPreferredAdminLangcode();
+    $user_preferred_admin_langcode = $register ? $language_interface->id : $account->getPreferredAdminLangcode(FALSE);
 
     // Is the user preferred language added?
     $user_language_added = FALSE;
@@ -286,6 +286,8 @@ public function form(array $form, FormStateInterface $form_state) {
       '#languages' => LanguageInterface::STATE_CONFIGURABLE,
       '#default_value' => $user_preferred_admin_langcode,
       '#access' => $show_admin_language,
+      '#empty_option' => $this->t('- No preference -'),
+      '#empty_value' => '',
     );
     // User entities contain both a langcode property (for identifying the
     // language of the entity data) and a preferred_langcode property (see
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 307cfc2..eeb8d55 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -366,28 +366,28 @@ public function getTimeZone() {
   /**
    * {@inheritdoc}
    */
-  function getPreferredLangcode($default = NULL) {
+  function getPreferredLangcode($fallback_to_default = TRUE) {
     $language_list = language_list();
     $preferred_langcode = $this->get('preferred_langcode')->value;
     if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) {
       return $language_list[$preferred_langcode]->id;
     }
     else {
-      return $default ? $default : language_default()->id;
+      return $fallback_to_default ? language_default()->id : '';
     }
   }
 
   /**
    * {@inheritdoc}
    */
-  function getPreferredAdminLangcode($default = NULL) {
+  function getPreferredAdminLangcode($fallback_to_default = TRUE) {
     $language_list = language_list();
     $preferred_langcode = $this->get('preferred_admin_langcode')->value;
     if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) {
       return $language_list[$preferred_langcode]->id;
     }
     else {
-      return $default ? $default : language_default()->id;
+      return $fallback_to_default ? language_default()->id : '';
     }
   }
 
diff --git a/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php b/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
index cdd2695..4697dfa 100644
--- a/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
+++ b/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
@@ -92,17 +92,12 @@ public static function create(ContainerInterface $container, array $configuratio
   public function getLangcode(Request $request = NULL) {
     $langcode = NULL;
 
-    // User preference (only for authenticated users).
-    if ($this->languageManager && $this->currentUser->isAuthenticated() && $this->isAdminPath($request)) {
-      $preferred_admin_langcode = $this->currentUser->getPreferredAdminLangcode();
-      $default_langcode = $this->languageManager->getDefaultLanguage()->id;
-      $languages = $this->languageManager->getLanguages();
-      if (!empty($preferred_admin_langcode) && $preferred_admin_langcode != $default_langcode && isset($languages[$preferred_admin_langcode])) {
-        $langcode = $preferred_admin_langcode;
-      }
+    // User preference (only for administrators).
+    if ($this->currentUser->hasPermission('access administration pages') && ($preferred_admin_langcode = $this->currentUser->getPreferredAdminLangcode(FALSE)) && $this->isAdminPath($request)) {
+      $langcode = $preferred_admin_langcode;
     }
 
-    // No language preference from the user or not on an admin path.
+    // Not an admin, no admin language preference or not on an admin path.
     return $langcode;
   }
 
diff --git a/core/modules/user/src/Tests/UserAdminLanguageTest.php b/core/modules/user/src/Tests/UserAdminLanguageTest.php
index d2b08b7..f1fbd0d 100644
--- a/core/modules/user/src/Tests/UserAdminLanguageTest.php
+++ b/core/modules/user/src/Tests/UserAdminLanguageTest.php
@@ -118,31 +118,37 @@ function testActualNegotiation() {
     $path = 'user/' . $this->adminUser->id() . '/edit';
     $this->drupalGet($path);
     $this->assertText('Language negotiation method: language-default');
+    $this->drupalGet('xx/' . $path);
+    $this->assertText('Language negotiation method: language-url');
 
     // Set a preferred language code for the user.
-    $path = 'user/' . $this->adminUser->id() . '/edit';
     $edit = array();
     $edit['preferred_admin_langcode'] = 'xx';
     $this->drupalPostForm($path, $edit, t('Save'));
 
     // Test negotiation with the URL method first. The admin method will only
     // be used if the URL method did not match.
-    $path = 'user/' . $this->adminUser->id() . '/edit';
     $this->drupalGet($path);
     $this->assertText('Language negotiation method: language-user-admin');
-    $path = 'xx/user/' . $this->adminUser->id() . '/edit';
-    $this->drupalGet($path);
+    $this->drupalGet('xx/' . $path);
     $this->assertText('Language negotiation method: language-url');
 
     // Test negotiation with the admin language method first. The admin method
     // will be used at all times.
     $this->setLanguageNegotiation(TRUE);
-    $path = 'user/' . $this->adminUser->id() . '/edit';
     $this->drupalGet($path);
     $this->assertText('Language negotiation method: language-user-admin');
-    $path = 'xx/user/' . $this->adminUser->id() . '/edit';
-    $this->drupalGet($path);
+    $this->drupalGet('xx/' . $path);
     $this->assertText('Language negotiation method: language-user-admin');
+
+    // Unset the preferred language code for the user.
+    $edit = array();
+    $edit['preferred_admin_langcode'] = '';
+    $this->drupalPostForm($path, $edit, t('Save'));
+    $this->drupalGet($path);
+    $this->assertText('Language negotiation method: language-default');
+    $this->drupalGet('xx/' . $path);
+    $this->assertText('Language negotiation method: language-url');
   }
 
   /**
