diff --git a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
index 6cbf234..8d608f1 100644
--- a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
+++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
@@ -34,7 +34,7 @@ public static function buildCancelLink(ConfirmFormInterface $form, Request $requ
     // If a destination is specified, that serves as the cancel link.
     if ($query->has('destination')) {
       $options = UrlHelper::parse($query->get('destination'));
-      $url = Url::fromUri('user-path:' . $options['path'], $options);
+      $url = Url::fromUri('user-path:/' . $options['path'], $options);
     }
     // Check for a route-based cancel link.
     else {
diff --git a/core/lib/Drupal/Core/Path/PathValidator.php b/core/lib/Drupal/Core/Path/PathValidator.php
index 51cdc2f..fcf0968 100644
--- a/core/lib/Drupal/Core/Path/PathValidator.php
+++ b/core/lib/Drupal/Core/Path/PathValidator.php
@@ -109,6 +109,9 @@ protected function getUrl($path, $access_check) {
     if ($parsed_url['path'] == '<front>') {
       return new Url('<front>', [], $options);
     }
+    elseif ($parsed_url['path'] == '<none>') {
+      return new Url('<none>', [], $options);
+    }
     elseif (UrlHelper::isExternal($path) && UrlHelper::isValid($path)) {
       if (empty($parsed_url['path'])) {
         return FALSE;
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index 859cf07..f8b901f 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -319,6 +319,30 @@ protected static function fromEntityUri(array $uri_parts, array $options, $uri)
   /**
    * Creates a new Url object for 'user-path:' URIs.
    *
+   * Important note: the URI minus the scheme can NOT simply be validated by a
+   * \Drupal\Core\Path\PathValidatorInterface implementation. The semantics of
+   * the 'user-path:' URI scheme are different:
+   * - PathValidatorInterface accepts paths without a leading slash (e.g.
+   *   'node/add') as well as 2 special paths: '<front>' and '<none>', which are
+   *   mapped to the correspondingly named routes.
+   * - 'user-path:' URIs store paths with a leading slash that represents the
+   *   root — i.e. the front page — (e.g. 'user-path:/node/add'), and doesn't
+   *   have any exceptions.
+   *
+   * To clarify, a few examples of path plus corresponding 'user-path:' URI:
+   * - 'node/add' -> 'user-path:/node/add'
+   * - 'node/add?foo=bar' -> 'user-path:/node/add?foo=bar'
+   * - 'node/add#kitten' -> 'user-path:/node/add#kitten'
+   * - '<front>' -> 'user-path:/'
+   * - '<front>foo=bar' -> 'user-path:/?foo=bar'
+   * - '<front>#kitten' -> 'user-path:/#kitten'
+   * - '<none>' -> 'user-path:'
+   * - '<none>foo=bar' -> 'user-path:?foo=bar'
+   * - '<none>#kitten' -> 'user-path:#kitten'
+   *
+   * Therefore, when using a PathValidatorInterface to validate 'user-path:'
+   * URIs, we must ensure to not use it in case of the
+   *
    * @param array $uri_parts
    *   Parts from an URI of the form user-path:{path} as from parse_url().
    * @param array $options
@@ -328,6 +352,21 @@ protected static function fromEntityUri(array $uri_parts, array $options, $uri)
    *   A new Url object for a 'user-path:' URI.
    */
   protected static function fromUserPathUri(array $uri_parts, array $options) {
+    // Both PathValidator::getUrlIfValidWithoutAccessCheck() and 'base:' URIs
+    // only accept/contain paths without a leading slash, unlike 'user-path:'
+    // URIs, for which the leading slash means "relative to Drupal root" and
+    // "relative to Symfony app root" (just like in Symfony/Drupal 8 routes).
+    if (empty($uri_parts['path'])) {
+      $uri_parts['path'] = '<none>';
+    }
+    elseif ($uri_parts['path'] === '/') {
+      $uri_parts['path'] = '<front>';
+    }
+    else {
+      // Remove the leading slash.
+      $uri_parts['path'] = substr($uri_parts['path'], 1);
+    }
+
     $url = \Drupal::pathValidator()
       ->getUrlIfValidWithoutAccessCheck($uri_parts['path']) ?: static::fromUri('base:' . $uri_parts['path'], $options);
     // Allow specifying additional options.
diff --git a/core/modules/field_ui/src/FieldUI.php b/core/modules/field_ui/src/FieldUI.php
index dcac29a..9ee73c7 100644
--- a/core/modules/field_ui/src/FieldUI.php
+++ b/core/modules/field_ui/src/FieldUI.php
@@ -61,7 +61,7 @@ public static function getNextDestination(array $destinations) {
         $options['query']['destinations'] = $destinations;
       }
       // Redirect to any given path within the same domain.
-      $next_destination = Url::fromUri('user-path:' . $options['path']);
+      $next_destination = Url::fromUri('user-path:/' . $options['path']);
     }
     return $next_destination;
   }
diff --git a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
index 6787c51..7546ef1 100644
--- a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
+++ b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
@@ -210,7 +210,7 @@ public function viewElements(FieldItemListInterface $items) {
           // attribute.
           // @todo Does RDF need a URL rather than an internal URI here?
           // @see \Drupal\rdf\Tests\Field\LinkFieldRdfaTest.
-          $content = str_replace('user-path:', '', $item->uri);
+          $content = str_replace('user-path:/', '', $item->uri);
           $item->_attributes += array('content' => $content);
         }
       }
diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
index e92fe53..ae85ebf 100644
--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -53,6 +53,20 @@ protected static function getUriAsDisplayableString($uri) {
     $scheme = parse_url($uri, PHP_URL_SCHEME);
     if ($scheme === 'user-path') {
       $uri_reference = explode(':', $uri, 2)[1];
+      // @todo Present the leading slash to the user and hence delete the next
+      //   block in https://www.drupal.org/node/2418017. There, we will also
+      //   remove the ability to enter '<front>' or '<none>', we'll expect '/'
+      //   and '' instead respectively.
+      $path = parse_url($uri, PHP_URL_PATH);
+      if ($path === '/') {
+        $uri_reference = '<front>' . substr($uri_reference, 1);
+      }
+      elseif (empty($path)) {
+        $uri_reference = '<none>' . $uri_reference;
+      }
+      else {
+        $uri_reference = ltrim($uri_reference, '/');
+      }
     }
     else {
       $uri_reference = $uri;
@@ -76,6 +90,31 @@ protected static function getUserEnteredStringAsUri($string) {
       // Users can enter relative URLs, but we need a valid URI, so add an
       // explicit scheme when necessary.
       if (parse_url($string, PHP_URL_SCHEME) === NULL) {
+        // @todo Present the leading slash to the user and hence delete the next
+        //   block in https://www.drupal.org/node/2418017. There, we will also
+        //   remove the ability to enter '<front>' or '<none>', we'll expect '/'
+        //   and '' instead respectively.
+        // Users can enter paths that don't start with a leading slash, we
+        // want to normalize them to have a leading slash. However, we don't
+        // want to add a leading slash if it already starts with one, or if it
+        // contains only a querystring or a fragment. Examples:
+        // - 'foo' -> '/foo'
+        // - '?foo=bar' -> '/?foo=bar'
+        // - '#foo' -> '/#foo'
+        // - '<front>' -> '/'
+        // - '<front>#foo' -> '/#foo'
+        // - '<none>' -> ''
+        // - '<none>#foo' -> '#foo'
+        if (strpos($string, '<front>') === 0) {
+          $string = '/' . substr($string, strlen('<front>'));
+        }
+        elseif (strpos($string, '<none>') === 0) {
+          $string = substr($string, strlen('<none>'));
+        }
+        elseif (!in_array($string[0], ['/', '?', '#'])) {
+          $string = '/' . $string;
+        }
+
         return 'user-path:' . $string;
       }
     }
diff --git a/core/modules/menu_link_content/menu_link_content.module b/core/modules/menu_link_content/menu_link_content.module
index 79c9935..59b12e1 100644
--- a/core/modules/menu_link_content/menu_link_content.module
+++ b/core/modules/menu_link_content/menu_link_content.module
@@ -58,7 +58,7 @@ function _menu_link_content_update_path_alias($path) {
   /** @var \Drupal\menu_link_content\MenuLinkContentInterface[] $entities */
   $entities = \Drupal::entityManager()
     ->getStorage('menu_link_content')
-    ->loadByProperties(['link__uri' => 'user-path:' . $path]);
+    ->loadByProperties(['link__uri' => 'user-path:/' . $path]);
   foreach ($entities as $menu_link) {
     $menu_link_manager->updateDefinition($menu_link->getPluginId(), $menu_link->getPluginDefinition(), FALSE);
   }
diff --git a/core/modules/menu_link_content/src/Tests/LinksTest.php b/core/modules/menu_link_content/src/Tests/LinksTest.php
index d7cee50..f7500ee 100644
--- a/core/modules/menu_link_content/src/Tests/LinksTest.php
+++ b/core/modules/menu_link_content/src/Tests/LinksTest.php
@@ -67,14 +67,14 @@ function createLinkHierarchy($module = 'menu_test') {
     );
 
     $parent = $base_options + array(
-      'link' => ['uri' => 'user-path:menu-test/hierarchy/parent'],
+      'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent'],
     );
     $link = entity_create('menu_link_content', $parent);
     $link->save();
     $links['parent'] = $link->getPluginId();
 
     $child_1 = $base_options + array(
-      'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child'],
+      'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child'],
       'parent' => $links['parent'],
     );
     $link = entity_create('menu_link_content', $child_1);
@@ -82,7 +82,7 @@ function createLinkHierarchy($module = 'menu_test') {
     $links['child-1'] = $link->getPluginId();
 
     $child_1_1 = $base_options + array(
-      'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child2/child'],
+      'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child2/child'],
       'parent' => $links['child-1'],
     );
     $link = entity_create('menu_link_content', $child_1_1);
@@ -90,7 +90,7 @@ function createLinkHierarchy($module = 'menu_test') {
     $links['child-1-1'] = $link->getPluginId();
 
     $child_1_2 = $base_options + array(
-      'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child2/child'],
+      'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child2/child'],
       'parent' => $links['child-1'],
     );
     $link = entity_create('menu_link_content', $child_1_2);
@@ -98,7 +98,7 @@ function createLinkHierarchy($module = 'menu_test') {
     $links['child-1-2'] = $link->getPluginId();
 
     $child_2 = $base_options + array(
-      'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child'],
+      'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child'],
       'parent' => $links['parent'],
     );
     $link = entity_create('menu_link_content', $child_2);
@@ -128,7 +128,7 @@ public function testCreateLink() {
     $options = array(
       'menu_name' => 'menu_test',
       'bundle' => 'menu_link_content',
-      'link' => [['uri' => 'user-path:<front>']],
+      'link' => [['uri' => 'user-path:/']],
     );
     $link = entity_create('menu_link_content', $options);
     $link->save();
diff --git a/core/modules/menu_link_content/src/Tests/MenuLinkContentDeriverTest.php b/core/modules/menu_link_content/src/Tests/MenuLinkContentDeriverTest.php
index d18a092..aaf2e7f 100644
--- a/core/modules/menu_link_content/src/Tests/MenuLinkContentDeriverTest.php
+++ b/core/modules/menu_link_content/src/Tests/MenuLinkContentDeriverTest.php
@@ -46,7 +46,7 @@ public function testRediscover() {
     // Set up a custom menu link pointing to a specific path.
     MenuLinkContent::create([
       'title' => 'Example',
-      'link' => [['uri' => 'user-path:example-path']],
+      'link' => [['uri' => 'user-path:/example-path']],
       'menu_name' => 'tools',
     ])->save();
     $menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters());
diff --git a/core/modules/menu_link_content/src/Tests/MenuLinkContentUITest.php b/core/modules/menu_link_content/src/Tests/MenuLinkContentUITest.php
index a5dc9fb..315d018 100644
--- a/core/modules/menu_link_content/src/Tests/MenuLinkContentUITest.php
+++ b/core/modules/menu_link_content/src/Tests/MenuLinkContentUITest.php
@@ -57,7 +57,7 @@ protected function getAdministratorPermissions() {
    */
   protected function createEntity($values, $langcode, $bundle_name = NULL) {
     $values['menu_name'] = 'tools';
-    $values['link']['uri'] = 'user-path:admin/structure/menu';
+    $values['link']['uri'] = 'user-path:/admin/structure/menu';
     $values['title'] = 'Test title';
 
     return parent::createEntity($values, $langcode, $bundle_name);
@@ -70,7 +70,7 @@ public function testTranslationLinkOnMenuEditForm() {
     $this->drupalGet('admin/structure/menu/manage/tools');
     $this->assertNoLink(t('Translate'));
 
-    $menu_link_content = MenuLinkContent::create(['menu_name' => 'tools', 'link' => ['uri' => 'user-path:admin/structure/menu']]);
+    $menu_link_content = MenuLinkContent::create(['menu_name' => 'tools', 'link' => ['uri' => 'user-path:/admin/structure/menu']]);
     $menu_link_content->save();
     $this->drupalGet('admin/structure/menu/manage/tools');
     $this->assertLink(t('Translate'));
diff --git a/core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php b/core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php
index 78fe0e3..af965af 100644
--- a/core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php
+++ b/core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php
@@ -64,7 +64,7 @@ public function testPathAliasChange() {
 
     $menu_link_content = MenuLinkContent::create([
       'title' => 'Menu title',
-      'link' => ['uri' => 'user-path:my-blog'],
+      'link' => ['uri' => 'user-path:/my-blog'],
       'menu_name' => 'tools',
     ]);
     $menu_link_content->save();
diff --git a/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php b/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php
index 7282ca2..b332f123 100644
--- a/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php
@@ -83,7 +83,7 @@ public function testMenuBlock() {
       'title' => 'Alpaca',
       'menu_name' => 'llama',
       'link' => [[
-        'uri' => 'user-path:<front>',
+        'uri' => 'user-path:/',
       ]],
       'bundle' => 'menu_name',
     ));
diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php
index fbcad78..f723b5c 100644
--- a/core/modules/menu_ui/src/Tests/MenuTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuTest.php
@@ -105,8 +105,8 @@ function testMenu() {
     $this->verifyAccess(403);
 
     foreach ($this->items as $item) {
-      // Paths were set as 'node/$nid'.
-      $node = Node::load(str_replace('user-path:node/', '', $item->link->uri));
+      // Menu link URIs are stored as 'user-path:/node/$nid'.
+      $node = Node::load(str_replace('user-path:/node/', '', $item->link->uri));
       $this->verifyMenuLink($item, $node);
     }
 
@@ -637,7 +637,7 @@ function addMenuLink($parent = '', $path = '<front>', $menu_name = 'tools', $exp
    * Attempts to add menu link with invalid path or no access permission.
    */
   function addInvalidMenuLink() {
-    foreach (array('-&-', 'admin/people/permissions', '#') as $link_path) {
+    foreach (array('-&-', 'admin/people/permissions') as $link_path) {
       $edit = array(
         'link[0][uri]' => $link_path,
         'title[0][value]' => 'title',
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/UserPathUri.php b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/UserPathUri.php
index fc8157c..ade7f8c 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/UserPathUri.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/UserPathUri.php
@@ -27,7 +27,7 @@ public function transform($value, MigrateExecutable $migrate_executable, Row $ro
     list($path) = $value;
 
     if (parse_url($path, PHP_URL_SCHEME) === NULL) {
-      return 'user-path:' . $path;
+      return 'user-path:/' . $path;
     }
     return $path;
   }
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateMenuLinkTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateMenuLinkTest.php
index 8b732fd..50b1d50 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateMenuLinkTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateMenuLinkTest.php
@@ -57,7 +57,7 @@ public function testMenuLinks() {
     $this->assertIdentical($menu_link->isEnabled(), TRUE);
     $this->assertIdentical($menu_link->isExpanded(), FALSE);
     $this->assertIdentical($menu_link->link->options, ['attributes' => ['title' => 'Test menu link 1']]);
-    $this->assertIdentical($menu_link->link->uri, 'user-path:user/login');
+    $this->assertIdentical($menu_link->link->uri, 'user-path:/user/login');
     $this->assertIdentical($menu_link->getWeight(), 15);
 
     $menu_link = entity_load('menu_link_content', 139);
@@ -67,7 +67,7 @@ public function testMenuLinks() {
     $this->assertIdentical($menu_link->isEnabled(), TRUE);
     $this->assertIdentical($menu_link->isExpanded(), TRUE);
     $this->assertIdentical($menu_link->link->options, ['query' => ['foo' => 'bar'], 'attributes' => ['title' => ['Test menu link 2']]]);
-    $this->assertIdentical($menu_link->link->uri, 'user-path:admin');
+    $this->assertIdentical($menu_link->link->uri, 'user-path:/admin');
     $this->assertIdentical($menu_link->getWeight(), 12);
 
     $menu_link = entity_load('menu_link_content', 140);
diff --git a/core/modules/rdf/src/Tests/Field/LinkFieldRdfaTest.php b/core/modules/rdf/src/Tests/Field/LinkFieldRdfaTest.php
index 4ed8d5c..34db4c5 100644
--- a/core/modules/rdf/src/Tests/Field/LinkFieldRdfaTest.php
+++ b/core/modules/rdf/src/Tests/Field/LinkFieldRdfaTest.php
@@ -67,7 +67,7 @@ public function testAllFormattersInternal() {
     // Set up test values.
     $this->testValue = 'admin';
     $this->entity = entity_create('entity_test', array());
-    $this->entity->{$this->fieldName}->uri = 'user-path:admin';
+    $this->entity->{$this->fieldName}->uri = 'user-path:/admin';
 
     // Set up the expected result.
     // AssertFormatterRdfa looks for a full path.
@@ -84,9 +84,9 @@ public function testAllFormattersInternal() {
    */
   public function testAllFormattersFront() {
     // Set up test values.
-    $this->testValue = '<front>';
+    $this->testValue = '/';
     $this->entity = entity_create('entity_test', array());
-    $this->entity->{$this->fieldName}->uri = 'user-path:<front>';
+    $this->entity->{$this->fieldName}->uri = 'user-path:/';
 
     // Set up the expected result.
     $expected_rdf = array(
diff --git a/core/modules/shortcut/src/Controller/ShortcutSetController.php b/core/modules/shortcut/src/Controller/ShortcutSetController.php
index 54833d2..528b02d 100644
--- a/core/modules/shortcut/src/Controller/ShortcutSetController.php
+++ b/core/modules/shortcut/src/Controller/ShortcutSetController.php
@@ -65,7 +65,7 @@ public function addShortcutLinkInline(ShortcutSetInterface $shortcut_set, Reques
         'title' => $name,
         'shortcut_set' => $shortcut_set->id(),
         'link' => array(
-          'uri' => 'user-path:' . $link,
+          'uri' => 'user-path:/' . $link,
         ),
       ));
 
diff --git a/core/modules/shortcut/src/Tests/ShortcutCacheTagsTest.php b/core/modules/shortcut/src/Tests/ShortcutCacheTagsTest.php
index 46e37cb..5265745 100644
--- a/core/modules/shortcut/src/Tests/ShortcutCacheTagsTest.php
+++ b/core/modules/shortcut/src/Tests/ShortcutCacheTagsTest.php
@@ -46,7 +46,7 @@ protected function createEntity() {
       'shortcut_set' => 'default',
       'title' => t('Llama'),
       'weight' => 0,
-      'link' => [['uri' => 'user-path:admin']],
+      'link' => [['uri' => 'user-path:/admin']],
     ));
     $shortcut->save();
 
diff --git a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
index b9c3ee5..945beb9 100644
--- a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
+++ b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
@@ -61,7 +61,7 @@ public function testShortcutLinkAdd() {
       $this->assertResponse(200);
       $saved_set = ShortcutSet::load($set->id());
       $paths = $this->getShortcutInformation($saved_set, 'link');
-      $this->assertTrue(in_array('user-path:' . $test_path, $paths), 'Shortcut created: ' . $test_path);
+      $this->assertTrue(in_array('user-path:/' . ($test_path == '<front>' ? '' : $test_path), $paths), 'Shortcut created: ' . $test_path);
       $this->assertLink($title, 0, String::format('Shortcut link %url found on the page.', ['%url' => $test_path]));
     }
     $saved_set = ShortcutSet::load($set->id());
@@ -157,7 +157,7 @@ public function testShortcutLinkChangePath() {
     $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $shortcut->getTitle(), 'link[0][uri]' => $new_link_path), t('Save'));
     $saved_set = ShortcutSet::load($set->id());
     $paths = $this->getShortcutInformation($saved_set, 'link');
-    $this->assertTrue(in_array('user-path:' . $new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
+    $this->assertTrue(in_array('user-path:/' . $new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
     $this->assertLinkByHref($new_link_path, 0, 'Shortcut with new path appears on the page.');
   }
 
diff --git a/core/modules/shortcut/src/Tests/ShortcutTestBase.php b/core/modules/shortcut/src/Tests/ShortcutTestBase.php
index 025826a..600176e 100644
--- a/core/modules/shortcut/src/Tests/ShortcutTestBase.php
+++ b/core/modules/shortcut/src/Tests/ShortcutTestBase.php
@@ -66,7 +66,7 @@ protected function setUp() {
         'title' => t('Add content'),
         'weight' => -20,
         'link' => array(
-          'uri' => 'user-path:node/add',
+          'uri' => 'user-path:/node/add',
         ),
       ));
       $shortcut->save();
@@ -76,7 +76,7 @@ protected function setUp() {
         'title' => t('All content'),
         'weight' => -19,
         'link' => array(
-          'uri' => 'user-path:admin/content',
+          'uri' => 'user-path:/admin/content',
         ),
       ));
       $shortcut->save();
diff --git a/core/modules/shortcut/src/Tests/ShortcutTranslationUITest.php b/core/modules/shortcut/src/Tests/ShortcutTranslationUITest.php
index 07b8bec..5f70a23 100644
--- a/core/modules/shortcut/src/Tests/ShortcutTranslationUITest.php
+++ b/core/modules/shortcut/src/Tests/ShortcutTranslationUITest.php
@@ -50,7 +50,7 @@ protected function getTranslatorPermissions() {
    * {@inheritdoc}
    */
   protected function createEntity($values, $langcode, $bundle_name = NULL) {
-    $values['link']['uri'] = 'user-path:user';
+    $values['link']['uri'] = 'user-path:/user';
     return parent::createEntity($values, $langcode, $bundle_name);
   }
 
diff --git a/core/modules/system/src/Tests/Common/UrlTest.php b/core/modules/system/src/Tests/Common/UrlTest.php
index 0b8a223..4511c8e 100644
--- a/core/modules/system/src/Tests/Common/UrlTest.php
+++ b/core/modules/system/src/Tests/Common/UrlTest.php
@@ -31,7 +31,7 @@ function testLinkXSS() {
     // Test \Drupal::l().
     $text = $this->randomMachineName();
     $path = "<SCRIPT>alert('XSS')</SCRIPT>";
-    $link = \Drupal::l($text, Url::fromUri('user-path:' . $path));
+    $link = \Drupal::l($text, Url::fromUri('user-path:/' . $path));
     $sanitized_path = check_url(Url::fromUri('base:' . $path)->toString());
     $this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by _l().', array('@path' => $path)));
 
diff --git a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
index fff190b..ab06c99 100644
--- a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
+++ b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
@@ -248,7 +248,7 @@ function testBreadCrumbs() {
       $menu_links = entity_load_multiple_by_properties('menu_link_content', array(
         'title' => $edit['title[0][value]'],
         // @todo Use link.uri once https://www.drupal.org/node/2391217 is in.
-        'link__uri' => 'user-path:taxonomy/term/' . $term->id(),
+        'link__uri' => 'user-path:/taxonomy/term/' . $term->id(),
       ));
       $tags[$name]['link'] = reset($menu_links);
       $parent_mlid = $tags[$name]['link']->getPluginId();
diff --git a/core/modules/system/src/Tests/Menu/MenuLinkTreeTest.php b/core/modules/system/src/Tests/Menu/MenuLinkTreeTest.php
index 912c4c9..0ec8dfd 100644
--- a/core/modules/system/src/Tests/Menu/MenuLinkTreeTest.php
+++ b/core/modules/system/src/Tests/Menu/MenuLinkTreeTest.php
@@ -67,9 +67,9 @@ public function testDeleteLinksInMenu() {
     \Drupal::entityManager()->getStorage('menu')->create(array('id' => 'menu1'))->save();
     \Drupal::entityManager()->getStorage('menu')->create(array('id' => 'menu2'))->save();
 
-    \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
-    \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
-    \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content'))->save();
+    \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
+    \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
+    \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:/menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content'))->save();
 
     $output = $this->linkTree->load('menu1', new MenuTreeParameters());
     $this->assertEqual(count($output), 2);
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php
index c99105a..c1b0a83 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php
@@ -55,7 +55,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     if (!$form_state->isValueEmpty('redirection')) {
       if (!$form_state->isValueEmpty('destination')) {
         // The destination is a random URL, so we can't use routed URLs.
-        $form_state->setRedirectUrl(Url::fromUri('user-path:' . $form_state->getValue('destination')));
+        $form_state->setRedirectUrl(Url::fromUri('user-path:/' . $form_state->getValue('destination')));
       }
     }
     else {
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index dddb382..52b2461 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -1248,7 +1248,7 @@ public function renderText($alter) {
           $more_link_path = Unicode::substr($more_link_path, Unicode::strlen($base_path));
         }
 
-        $more_link = \Drupal::l($more_link_text, CoreUrl::fromUri('user-path:' . $more_link_path), array('attributes' => array('class' => array('views-more-link'))));
+        $more_link = \Drupal::l($more_link_text, CoreUrl::fromUri('user-path:/' . $more_link_path), array('attributes' => array('class' => array('views-more-link'))));
 
         $suffix .= " " . $more_link;
       }
diff --git a/core/modules/views/src/Plugin/views/field/Url.php b/core/modules/views/src/Plugin/views/field/Url.php
index 3635df8..b520aed 100644
--- a/core/modules/views/src/Plugin/views/field/Url.php
+++ b/core/modules/views/src/Plugin/views/field/Url.php
@@ -46,7 +46,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   public function render(ResultRow $values) {
     $value = $this->getValue($values);
     if (!empty($this->options['display_as_link'])) {
-      return \Drupal::l($this->sanitizeValue($value), CoreUrl::fromUri('user-path:' . $value), array('html' => TRUE));
+      return \Drupal::l($this->sanitizeValue($value), CoreUrl::fromUri('user-path:/' . $value), array('html' => TRUE));
     }
     else {
       return $this->sanitizeValue($value, 'url');
diff --git a/core/modules/views_ui/src/ViewListBuilder.php b/core/modules/views_ui/src/ViewListBuilder.php
index b4a53c6..9e094db 100644
--- a/core/modules/views_ui/src/ViewListBuilder.php
+++ b/core/modules/views_ui/src/ViewListBuilder.php
@@ -263,7 +263,7 @@ protected function getDisplayPaths(EntityInterface $view) {
       if ($display->hasPath()) {
         $path = $display->getPath();
         if ($view->status() && strpos($path, '%') === FALSE) {
-          $all_paths[] = \Drupal::l('/' . $path, Url::fromUri('user-path:' . $path));
+          $all_paths[] = \Drupal::l('/' . $path, Url::fromUri('user-path:/' . $path));
         }
         else {
           $all_paths[] = String::checkPlain('/' . $path);
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 7f0d8bd..08e887c 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -723,7 +723,7 @@ public function renderPreview($display_id, $args = array()) {
               Xss::filterAdmin($this->executable->getTitle()),
             );
             if (isset($path)) {
-              $path = \Drupal::l($path, Url::fromUri('user-path:' . $path));
+              $path = \Drupal::l($path, Url::fromUri('user-path:/' . $path));
             }
             else {
               $path = t('This display has no path.');
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index 86dd057..f9466ff 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -58,7 +58,7 @@ function standard_install() {
     'shortcut_set' => 'default',
     'title' => t('Add content'),
     'weight' => -20,
-    'link' => array('uri' => 'user-path:node/add'),
+    'link' => array('uri' => 'user-path:/node/add'),
   ));
   $shortcut->save();
 
@@ -66,7 +66,7 @@ function standard_install() {
     'shortcut_set' => 'default',
     'title' => t('All content'),
     'weight' => -19,
-    'link' => array('uri' => 'user-path:admin/content'),
+    'link' => array('uri' => 'user-path:/admin/content'),
   ));
   $shortcut->save();
 
diff --git a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
index 0e2471c..3069b74 100644
--- a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
+++ b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
@@ -81,6 +81,18 @@ public function testIsValidWithFrontpage() {
   }
 
   /**
+   * Tests the isValid() method for <none> (used for jumplinks).
+   *
+   * @covers ::isValid
+   */
+  public function testIsValidWithNone() {
+    $this->accessAwareRouter->expects($this->never())
+      ->method('match');
+
+    $this->assertTrue($this->pathValidator->isValid('<none>'));
+  }
+
+  /**
    * Tests the isValid() method for an external URL.
    *
    * @covers ::isValid
diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php
index 3f0ec3e..4096e3d 100644
--- a/core/tests/Drupal/Tests/Core/UrlTest.php
+++ b/core/tests/Drupal/Tests/Core/UrlTest.php
@@ -180,7 +180,7 @@ public function testFromRoutedPathWithInvalidRoute() {
       ->method('getUrlIfValidWithoutAccessCheck')
       ->with('invalid-path')
       ->willReturn(FALSE);
-    $url = Url::fromUri('user-path:invalid-path');
+    $url = Url::fromUri('user-path:/invalid-path');
     $this->assertSame(FALSE, $url->isRouted());
     $this->assertSame('base:invalid-path', $url->getUri());
   }
@@ -196,7 +196,7 @@ public function testFromRoutedPathWithValidRoute() {
       ->method('getUrlIfValidWithoutAccessCheck')
       ->with('valid-path')
       ->willReturn($url);
-    $result_url = Url::fromUri('user-path:valid-path');
+    $result_url = Url::fromUri('user-path:/valid-path');
     $this->assertSame($url, $result_url);
   }
 
@@ -602,8 +602,11 @@ public function testToUriStringForUserPath($uri, $options, $uri_string) {
     $url = Url::fromRoute('entity.test_entity.canonical', ['test_entity' => '1']);
     $this->pathValidator->expects($this->any())
       ->method('getUrlIfValidWithoutAccessCheck')
-      ->with('test-entity/1')
-      ->willReturn($url);
+      ->willReturnMap([
+        ['test-entity/1', $url],
+        ['<front>', Url::fromRoute('<front>')],
+        ['<none>', Url::fromRoute('<none>')],
+      ]);
     $url = Url::fromUri($uri, $options);
     $this->assertSame($url->toUriString(), $uri_string);
   }
@@ -613,10 +616,23 @@ public function testToUriStringForUserPath($uri, $options, $uri_string) {
    */
   public function providerTestToUriStringForUserPath() {
     return [
-      ['user-path:test-entity/1', [], 'route:entity.test_entity.canonical;test_entity=1'],
-      ['user-path:test-entity/1', ['fragment' => 'top'], 'route:entity.test_entity.canonical;test_entity=1#top'],
-      ['user-path:test-entity/1', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
-      ['user-path:test-entity/1?page=2#top', [], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
+      // The four permutations of a regular path.
+      ['user-path:/test-entity/1', [], 'route:entity.test_entity.canonical;test_entity=1'],
+      ['user-path:/test-entity/1', ['fragment' => 'top'], 'route:entity.test_entity.canonical;test_entity=1#top'],
+      ['user-path:/test-entity/1', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
+      ['user-path:/test-entity/1?page=2#top', [], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
+
+      // The four permutations of the special '<front>' path.
+      ['user-path:/', [], 'route:<front>'],
+      ['user-path:/', ['fragment' => 'top'], 'route:<front>#top'],
+      ['user-path:/', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:<front>?page=2#top'],
+      ['user-path:/?page=2#top', [], 'route:<front>?page=2#top'],
+
+      // The four permutations of the special '<none>' path.
+      ['user-path:', [], 'route:<none>'],
+      ['user-path:', ['fragment' => 'top'], 'route:<none>#top'],
+      ['user-path:', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:<none>?page=2#top'],
+      ['user-path:?page=2#top', [], 'route:<none>?page=2#top'],
     ];
   }
 
