diff --git a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
index ae92b08..8422db2 100644
--- a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
@@ -66,7 +66,7 @@ protected static function getPriority() {
    */
   public function on403(GetResponseForExceptionEvent $event) {
     $path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.403'));
-    $this->makeSubrequest($event, $path, Response::HTTP_FORBIDDEN);
+    $this->makeSubrequest($event, trim($path, '/'), Response::HTTP_FORBIDDEN);
   }
 
   /**
@@ -74,7 +74,7 @@ public function on403(GetResponseForExceptionEvent $event) {
    */
   public function on404(GetResponseForExceptionEvent $event) {
     $path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.404'));
-    $this->makeSubrequest($event, $path, Response::HTTP_NOT_FOUND);
+    $this->makeSubrequest($event, trim($path, '/'), Response::HTTP_NOT_FOUND);
   }
 
 }
diff --git a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
index a73cf31..d35457d 100644
--- a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
@@ -58,7 +58,7 @@ public function __construct(AliasManagerInterface $alias_manager, CurrentPathSta
   public function onKernelController(FilterControllerEvent $event) {
     // Set the cache key on the alias manager cache decorator.
     if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
-      $this->aliasManager->setCacheKey(trim($this->currentPath->getPath($event->getRequest()), '/'));
+      $this->aliasManager->setCacheKey(rtrim($this->currentPath->getPath($event->getRequest()), '/'));
     }
   }
 
diff --git a/core/lib/Drupal/Core/Path/AliasManager.php b/core/lib/Drupal/Core/Path/AliasManager.php
index 1eac0f8..2e04097 100644
--- a/core/lib/Drupal/Core/Path/AliasManager.php
+++ b/core/lib/Drupal/Core/Path/AliasManager.php
@@ -187,6 +187,9 @@ public function getPathByAlias($alias, $langcode = NULL) {
    * {@inheritdoc}
    */
   public function getAliasByPath($path, $langcode = NULL) {
+    if ($path[0] !== '/') {
+      throw new \InvalidArgumentException(sprintf('Source path %s has to start with a slash.', $path));
+    }
     // If no language is explicitly specified we default to the current URL
     // language. If we used a language different from the one conveyed by the
     // requested URL, we might end up being unable to check if there is a path
@@ -196,7 +199,7 @@ public function getAliasByPath($path, $langcode = NULL) {
     // Check the path whitelist, if the top-level part before the first /
     // is not in the list, then there is no need to do anything further,
     // it is not in the database.
-    if (empty($path) || !$this->whitelist->get(strtok($path, '/'))) {
+    if ($path === '/' || !$this->whitelist->get(strtok(trim($path, '/'), '/'))) {
       return $path;
     }
 
diff --git a/core/lib/Drupal/Core/Path/AliasManagerInterface.php b/core/lib/Drupal/Core/Path/AliasManagerInterface.php
index e87edaa..177d1a4 100644
--- a/core/lib/Drupal/Core/Path/AliasManagerInterface.php
+++ b/core/lib/Drupal/Core/Path/AliasManagerInterface.php
@@ -19,6 +19,9 @@
    *
    * @return string
    *   The path represented by alias, or the alias if no path was found.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown when the path does not start with a slash.
    */
   public function getPathByAlias($alias, $langcode = NULL);
 
@@ -32,6 +35,9 @@ public function getPathByAlias($alias, $langcode = NULL);
    *
    * @return string
    *   An alias that represents the path, or path if no alias was found.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown when the path does not start with a slash.
    */
   public function getAliasByPath($path, $langcode = NULL);
 
diff --git a/core/lib/Drupal/Core/Path/AliasStorage.php b/core/lib/Drupal/Core/Path/AliasStorage.php
index 033f6f2..899c39e 100644
--- a/core/lib/Drupal/Core/Path/AliasStorage.php
+++ b/core/lib/Drupal/Core/Path/AliasStorage.php
@@ -49,6 +49,14 @@ public function __construct(Connection $connection, ModuleHandlerInterface $modu
    */
   public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid = NULL) {
 
+    if ($source[0] !== '/') {
+      throw new \InvalidArgumentException(sprintf('Source path %s has to start with a slash.', $source));
+    }
+
+    if ($alias[0] !== '/') {
+      throw new \InvalidArgumentException(sprintf('Alias path %s has to start with a slash.', $alias));
+    }
+
     $fields = array(
       'source' => $source,
       'alias' => $alias,
diff --git a/core/lib/Drupal/Core/Path/AliasStorageInterface.php b/core/lib/Drupal/Core/Path/AliasStorageInterface.php
index 8d82846..5ac77a3 100644
--- a/core/lib/Drupal/Core/Path/AliasStorageInterface.php
+++ b/core/lib/Drupal/Core/Path/AliasStorageInterface.php
@@ -29,12 +29,15 @@
    * @return array|false
    *   FALSE if the path could not be saved or an associative array containing
    *   the following keys:
-   *   - source (string): The internal system path.
-   *   - alias (string): The URL alias.
+   *   - source (string): The internal system path with a starting slash.
+   *   - alias (string): The URL alias with a starting slash.
    *   - pid (int): Unique path alias identifier.
    *   - langcode (string): The language code of the alias.
    *   - original: For updates, an array with source, alias and langcode with
    *     the previous values.
+   *
+   * @thrown \InvalidArgumentException
+   *   Thrown when either the source or alias has not a starting slash.
    */
   public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid = NULL);
 
@@ -47,8 +50,8 @@ public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NO
    * @return array|false
    *   FALSE if no alias was found or an associative array containing the
    *   following keys:
-   *   - source (string): The internal system path.
-   *   - alias (string): The URL alias.
+   *   - source (string): The internal system path with a starting slash.
+   *   - alias (string): The URL alias with a starting slash.
    *   - pid (int): Unique path alias identifier.
    *   - langcode (string): The language code of the alias.
    */
diff --git a/core/lib/Drupal/Core/Path/AliasWhitelist.php b/core/lib/Drupal/Core/Path/AliasWhitelist.php
index 38ace76..fc26b77 100644
--- a/core/lib/Drupal/Core/Path/AliasWhitelist.php
+++ b/core/lib/Drupal/Core/Path/AliasWhitelist.php
@@ -107,7 +107,7 @@ public function get($offset) {
    * {@inheritdoc}
    */
   public function resolveCacheMiss($root) {
-    $exists = $this->aliasStorage->pathHasMatchingAlias($root);
+    $exists = $this->aliasStorage->pathHasMatchingAlias('/' . $root);
     $this->storage[$root] = $exists;
     $this->persist($root);
     if ($exists) {
diff --git a/core/lib/Drupal/Core/Path/PathMatcher.php b/core/lib/Drupal/Core/Path/PathMatcher.php
index a7eed13..1f7b88c 100644
--- a/core/lib/Drupal/Core/Path/PathMatcher.php
+++ b/core/lib/Drupal/Core/Path/PathMatcher.php
@@ -101,7 +101,7 @@ public function isFrontPage() {
       // route match, like on exception responses.
       if ($this->routeMatch->getRouteName()) {
         $url = Url::fromRouteMatch($this->routeMatch);
-        $this->isCurrentFrontPage = ($url->getRouteName() && $url->getInternalPath() === $this->getFrontPagePath());
+        $this->isCurrentFrontPage = ($url->getRouteName() && '/' . $url->getInternalPath() === $this->getFrontPagePath());
       }
     }
     return $this->isCurrentFrontPage;
@@ -116,8 +116,6 @@ public function isFrontPage() {
   protected function getFrontPagePath() {
     // Lazy-load front page config.
     if (!isset($this->frontPage)) {
-      // @todo page.front should store the route name, see
-      //   https://www.drupal.org/node/2371823
       $this->frontPage = $this->configFactory->get('system.site')
         ->get('page.front');
     }
diff --git a/core/lib/Drupal/Core/Path/PathValidator.php b/core/lib/Drupal/Core/Path/PathValidator.php
index f6132d0..689625c 100644
--- a/core/lib/Drupal/Core/Path/PathValidator.php
+++ b/core/lib/Drupal/Core/Path/PathValidator.php
@@ -96,6 +96,8 @@ public function getUrlIfValidWithoutAccessCheck($path) {
    * Helper for getUrlIfValid() and getUrlIfValidWithoutAccessCheck().
    */
   protected function getUrl($path, $access_check) {
+    $path = ltrim($path, '/');
+
     $parsed_url = UrlHelper::parse($path);
 
     $options = [];
@@ -119,7 +121,6 @@ protected function getUrl($path, $access_check) {
       return Url::fromUri($path);
     }
 
-    $path = ltrim($path, '/');
     $request = Request::create('/' . $path);
     $attributes = $this->getPathAttributes($path, $request, $access_check);
 
@@ -155,10 +156,10 @@ protected function getPathAttributes($path, Request $request, $access_check) {
       $router = $this->accessAwareRouter;
     }
 
-    $path = $this->pathProcessor->processInbound($path, $request);
+    $path = $this->pathProcessor->processInbound('/' . $path, $request);
 
     try {
-      return $router->match('/' . $path);
+      return $router->match($path);
     }
     catch (ResourceNotFoundException $e) {
       return FALSE;
diff --git a/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php b/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
index a02da88..9fb3d81 100644
--- a/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
+++ b/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
@@ -18,7 +18,7 @@
    * Processes the inbound path.
    *
    * @param string $path
-   *   The path to process.
+   *   The path to process, with a starting slash.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The HttpRequest object representing the current request.
diff --git a/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php
index 87e7e75..bd1d8c1 100644
--- a/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php
+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php
@@ -39,7 +39,7 @@ public function __construct(ConfigFactoryInterface $config) {
    * Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
    */
   public function processInbound($path, Request $request) {
-    if (empty($path)) {
+    if ($path === '/') {
       $path = $this->config->get('system.site')->get('page.front');
     }
     return $path;
@@ -50,8 +50,8 @@ public function processInbound($path, Request $request) {
    */
   public function processOutbound($path, &$options = array(), Request $request = NULL, CacheableMetadata $cacheable_metadata = NULL) {
     // The special path '<front>' links to the default front page.
-    if ($path == '<front>') {
-      $path = '';
+    if ($path === '/<front>') {
+      $path = '/';
     }
     return $path;
   }
diff --git a/core/lib/Drupal/Core/Routing/RouteProvider.php b/core/lib/Drupal/Core/Routing/RouteProvider.php
index 54aeef2..278b486 100644
--- a/core/lib/Drupal/Core/Routing/RouteProvider.php
+++ b/core/lib/Drupal/Core/Routing/RouteProvider.php
@@ -140,14 +140,16 @@ public function getRouteCollectionForRequest(Request $request) {
       return $cached->data['routes'];
     }
     else {
-      $path = trim($request->getPathInfo(), '/');
+      // Just trim on the right side.
+      $path = $request->getPathInfo();
+      $path = $path === '/' ? $path : rtrim($request->getPathInfo(), '/');
       $path = $this->pathProcessor->processInbound($path, $request);
-      $this->currentPath->setPath('/' . $path, $request);
+      $this->currentPath->setPath($path, $request);
       // Incoming path processors may also set query parameters.
       $query_parameters = $request->query->all();
-      $routes = $this->getRoutesByPath('/' . rtrim($path, '/'));
+      $routes = $this->getRoutesByPath(rtrim($path, '/'));
       $cache_value = [
-        'path' => '/' . $path,
+        'path' => $path,
         'query' => $query_parameters,
         'routes' => $routes,
       ];
diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php
index e30a203..bd3c1a0 100644
--- a/core/lib/Drupal/Core/Routing/UrlGenerator.php
+++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php
@@ -435,7 +435,7 @@ public function generateFromPath($path = NULL, $options = array(), $collect_cach
       return $collect_cacheability_metadata ? $generated_url->setGeneratedUrl($url) : $url;
     }
     else {
-      $path = ltrim($this->processPath($path, $options, $generated_url), '/');
+      $path = ltrim($this->processPath('/' . $path, $options, $generated_url), '/');
     }
 
     if (!isset($options['script'])) {
@@ -488,7 +488,7 @@ protected function processPath($path, &$options = array(), CacheableMetadata $ca
       $actual_path = $path;
       $query_string = '';
     }
-    $path = '/' . $this->pathProcessor->processOutbound(trim($actual_path, '/'), $options, $this->requestStack->getCurrentRequest(), $cacheable_metadata);
+    $path = $this->pathProcessor->processOutbound($actual_path === '/' ? $actual_path : rtrim($actual_path, '/'), $options, $this->requestStack->getCurrentRequest(), $cacheable_metadata);
     $path .= $query_string;
     return $path;
   }
diff --git a/core/modules/block/src/Tests/BlockTest.php b/core/modules/block/src/Tests/BlockTest.php
index d6e0999..8c65bc3 100644
--- a/core/modules/block/src/Tests/BlockTest.php
+++ b/core/modules/block/src/Tests/BlockTest.php
@@ -35,7 +35,7 @@ function testBlockVisibility() {
     );
     // Set the block to be hidden on any user path, and to be shown only to
     // authenticated users.
-    $edit['visibility[request_path][pages]'] = 'user*';
+    $edit['visibility[request_path][pages]'] = '/user*';
     $edit['visibility[request_path][negate]'] = TRUE;
     $edit['visibility[user_role][roles][' . RoleInterface::AUTHENTICATED_ID . ']'] = TRUE;
     $this->drupalGet('admin/structure/block/add/' . $block_name . '/' . $default_theme);
diff --git a/core/modules/block/src/Tests/BlockTestBase.php b/core/modules/block/src/Tests/BlockTestBase.php
index 1f3cb74..c0d96ad 100644
--- a/core/modules/block/src/Tests/BlockTestBase.php
+++ b/core/modules/block/src/Tests/BlockTestBase.php
@@ -39,7 +39,7 @@ protected function setUp() {
     parent::setUp();
 
     // Use the test page as the front page.
-    $this->config('system.site')->set('page.front', 'test-page')->save();
+    $this->config('system.site')->set('page.front', '/test-page')->save();
 
     // Create Full HTML text format.
     $full_html_format = entity_create('filter_format', array(
diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php
index 9ed809f..a94e26a 100644
--- a/core/modules/config/src/Tests/ConfigSchemaTest.php
+++ b/core/modules/config/src/Tests/ConfigSchemaTest.php
@@ -293,7 +293,7 @@ function testSchemaData() {
     $meta = \Drupal::service('config.typed')->get('system.site');
     $property = $meta->get('page')->get('front');
     $this->assertTrue($property instanceof StringInterface, 'Got the right wrapper fo the page.front property.');
-    $this->assertEqual($property->getValue(), 'user/login', 'Got the right value for page.front data.');
+    $this->assertEqual($property->getValue(), '/user/login', 'Got the right value for page.front data.');
     $definition = $property->getDataDefinition();
     $this->assertTrue(empty($definition['translatable']), 'Got the right translatability setting for page.front data.');
 
@@ -301,13 +301,13 @@ function testSchemaData() {
     $list = $meta->get('page')->getElements();
     $this->assertEqual(count($list), 3, 'Got a list with the right number of properties for site page data');
     $this->assertTrue(isset($list['front']) && isset($list['403']) && isset($list['404']), 'Got a list with the right properties for site page data.');
-    $this->assertEqual($list['front']->getValue(), 'user/login', 'Got the right value for page.front data from the list.');
+    $this->assertEqual($list['front']->getValue(), '/user/login', 'Got the right value for page.front data from the list.');
 
     // And test some TypedConfigInterface methods.
     $properties = $list;
     $this->assertTrue(count($properties) == 3 && $properties['front'] == $list['front'], 'Got the right properties for site page.');
     $values = $meta->get('page')->toArray();
-    $this->assertTrue(count($values) == 3 && $values['front'] == 'user/login', 'Got the right property values for site page.');
+    $this->assertTrue(count($values) == 3 && $values['front'] == '/user/login', 'Got the right property values for site page.');
 
     // Now let's try something more complex, with nested objects.
     $wrapper = \Drupal::service('config.typed')->get('image.style.large');
diff --git a/core/modules/config/src/Tests/ConfigSingleImportExportTest.php b/core/modules/config/src/Tests/ConfigSingleImportExportTest.php
index a51fda8..688d867 100644
--- a/core/modules/config/src/Tests/ConfigSingleImportExportTest.php
+++ b/core/modules/config/src/Tests/ConfigSingleImportExportTest.php
@@ -134,7 +134,7 @@ public function testImportSimpleConfiguration() {
     $this->drupalPostForm('admin/config/development/configuration/single/import', $edit, t('Import'));
     $this->assertRaw(t('Are you sure you want to update the %name @type?', array('%name' => $config->getName(), '@type' => 'simple configuration')));
     $this->drupalPostForm(NULL, array(), t('Confirm'));
-    $this->drupalGet('/');
+    $this->drupalGet('');
     $this->assertText('Test simple import');
   }
 
diff --git a/core/modules/image/src/PathProcessor/PathProcessorImageStyles.php b/core/modules/image/src/PathProcessor/PathProcessorImageStyles.php
index 4418476..c723860 100644
--- a/core/modules/image/src/PathProcessor/PathProcessorImageStyles.php
+++ b/core/modules/image/src/PathProcessor/PathProcessorImageStyles.php
@@ -32,11 +32,11 @@ class PathProcessorImageStyles implements InboundPathProcessorInterface {
    */
   public function processInbound($path, Request $request) {
     $directory_path = file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath();
-    if (strpos($path, $directory_path . '/styles/') === 0) {
-      $path_prefix = $directory_path . '/styles/';
+    if (strpos($path, '/' . $directory_path . '/styles/') === 0) {
+      $path_prefix = '/' . $directory_path . '/styles/';
     }
-    elseif (strpos($path, 'system/files/styles/') === 0) {
-      $path_prefix = 'system/files/styles/';
+    elseif (strpos($path, '/system/files/styles/') === 0) {
+      $path_prefix = '/system/files/styles/';
     }
     else {
       return $path;
diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
index 6ea4aee..0c57d8b 100644
--- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
@@ -105,14 +105,14 @@ public function getLangcode(Request $request = NULL) {
    */
   public function processInbound($path, Request $request) {
     $config = $this->config->get('language.negotiation')->get('url');
-    $parts = explode('/', $path);
+    $parts = explode('/', trim($path, '/'));
     $prefix = array_shift($parts);
 
     // Search prefix within added languages.
     foreach ($this->languageManager->getLanguages() as $language) {
       if (isset($config['prefixes'][$language->getId()]) && $config['prefixes'][$language->getId()] == $prefix) {
         // Rebuild $path with the language removed.
-        $path = implode('/', $parts);
+        $path = '/' . implode('/', $parts);
         break;
       }
     }
diff --git a/core/modules/link/src/Tests/LinkFieldTest.php b/core/modules/link/src/Tests/LinkFieldTest.php
index d2242d8..558e78f 100644
--- a/core/modules/link/src/Tests/LinkFieldTest.php
+++ b/core/modules/link/src/Tests/LinkFieldTest.php
@@ -92,7 +92,7 @@ function testURLValidation() {
     $this->assertRaw('placeholder="http://example.com"');
 
     // Create a path alias.
-    \Drupal::service('path.alias_storage')->save('admin', 'a/path/alias');
+    \Drupal::service('path.alias_storage')->save('/admin', '/a/path/alias');
 
     // Create a node to test the link widget.
     $node = $this->drupalCreateNode();
diff --git a/core/modules/locale/src/Tests/LocalePathTest.php b/core/modules/locale/src/Tests/LocalePathTest.php
index 8270f9b..820814e 100644
--- a/core/modules/locale/src/Tests/LocalePathTest.php
+++ b/core/modules/locale/src/Tests/LocalePathTest.php
@@ -32,7 +32,7 @@ protected function setUp() {
     parent::setUp();
 
     $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
-    $this->config('system.site')->set('page.front', 'node')->save();
+    $this->config('system.site')->set('page.front', '/node')->save();
   }
 
   /**
@@ -74,8 +74,8 @@ public function testPathLanguageConfiguration() {
     $path = 'admin/config/search/path/add';
     $english_path = $this->randomMachineName(8);
     $edit = array(
-      'source'   => 'node/' . $node->id(),
-      'alias'    => $english_path,
+      'source'   => '/node/' . $node->id(),
+      'alias'    => '/' . $english_path,
       'langcode' => 'en',
     );
     $this->drupalPostForm($path, $edit, t('Save'));
@@ -83,8 +83,8 @@ public function testPathLanguageConfiguration() {
     // Create a path alias in new custom language.
     $custom_language_path = $this->randomMachineName(8);
     $edit = array(
-      'source'   => 'node/' . $node->id(),
-      'alias'    => $custom_language_path,
+      'source'   => '/node/' . $node->id(),
+      'alias'    => '/' . $custom_language_path,
       'langcode' => $langcode,
     );
     $this->drupalPostForm($path, $edit, t('Save'));
@@ -102,16 +102,16 @@ public function testPathLanguageConfiguration() {
 
     // Check priority of language for alias by source path.
     $edit = array(
-      'source'   => 'node/' . $node->id(),
-      'alias'    => $custom_path,
+      'source'   => '/node/' . $node->id(),
+      'alias'    => '/' . $custom_path,
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
     );
     $this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
-    $lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $node->id(), 'en');
-    $this->assertEqual($english_path, $lookup_path, 'English language alias has priority.');
+    $lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $node->id(), 'en');
+    $this->assertEqual('/' . $english_path, $lookup_path, 'English language alias has priority.');
     // Same check for language 'xx'.
-    $lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $node->id(), $prefix);
-    $this->assertEqual($custom_language_path, $lookup_path, 'Custom language alias has priority.');
+    $lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $node->id(), $prefix);
+    $this->assertEqual('/' . $custom_language_path, $lookup_path, 'Custom language alias has priority.');
     $this->container->get('path.alias_storage')->delete($edit);
 
     // Create language nodes to check priority of aliases.
@@ -120,8 +120,8 @@ public function testPathLanguageConfiguration() {
 
     // Assign a custom path alias to the first node with the English language.
     $edit = array(
-      'source'   => 'node/' . $first_node->id(),
-      'alias'    => $custom_path,
+      'source'   => '/node/' . $first_node->id(),
+      'alias'    => '/' . $custom_path,
       'langcode' => $first_node->language()->getId(),
     );
     $this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
@@ -129,8 +129,8 @@ public function testPathLanguageConfiguration() {
     // Assign a custom path alias to second node with
     // LanguageInterface::LANGCODE_NOT_SPECIFIED.
     $edit = array(
-      'source'   => 'node/' . $second_node->id(),
-      'alias'    => $custom_path,
+      'source'   => '/node/' . $second_node->id(),
+      'alias'    => '/' . $custom_path,
       'langcode' => $second_node->language()->getId(),
     );
     $this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
diff --git a/core/modules/menu_link_content/menu_link_content.module b/core/modules/menu_link_content/menu_link_content.module
index a413eae..aee8424 100644
--- a/core/modules/menu_link_content/menu_link_content.module
+++ b/core/modules/menu_link_content/menu_link_content.module
@@ -57,7 +57,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' => 'internal:/' . $path]);
+    ->loadByProperties(['link.uri' => 'internal:' . $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/PathAliasMenuLinkContentTest.php b/core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php
index 3caf26f..3cdec3f 100644
--- a/core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php
+++ b/core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php
@@ -59,7 +59,7 @@ public function testPathAliasChange() {
 
     /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
     $path_alias_storage = \Drupal::service('path.alias_storage');
-    $alias = $path_alias_storage->save('test-page', 'my-blog');
+    $alias = $path_alias_storage->save('/test-page', '/my-blog');
     $pid = $alias['pid'];
 
     $menu_link_content = MenuLinkContent::create([
@@ -73,7 +73,7 @@ public function testPathAliasChange() {
     $this->assertEqual('test_page_test.test_page', $tree[$menu_link_content->getPluginId()]->link->getPluginDefinition()['route_name']);
 
     // Saving an alias should clear the alias manager cache.
-    $path_alias_storage->save('test-render-title', 'my-blog', LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid);
+    $path_alias_storage->save('/test-render-title', '/my-blog', LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid);
 
     $tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters());
     $this->assertEqual('test_page_test.render_title', $tree[$menu_link_content->getPluginId()]->link->getPluginDefinition()['route_name']);
diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php
index 59616e7..3a1bac5 100644
--- a/core/modules/menu_ui/src/Tests/MenuTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuTest.php
@@ -289,7 +289,7 @@ function doMenuTests() {
     $node5 = $this->drupalCreateNode(array(
       'type' => 'article',
       'path' => array(
-        'alias' => 'node5',
+        'alias' => '/node5',
       ),
     ));
 
diff --git a/core/modules/migrate/config/schema/migrate.data_types.schema.yml b/core/modules/migrate/config/schema/migrate.data_types.schema.yml
index edb628a..d887785 100644
--- a/core/modules/migrate/config/schema/migrate.data_types.schema.yml
+++ b/core/modules/migrate/config/schema/migrate.data_types.schema.yml
@@ -14,6 +14,10 @@ migrate_destination:
 migrate_source:
   type: migrate_plugin
   label: 'Source'
+  mapping:
+    constants:
+      type: ignore
+      label: 'Constants'
 
 # Base schema for migrate source plugins that extend
 # \Drupal\migrate\Plugin\migrate\source\SqlBase.
diff --git a/core/modules/migrate/config/schema/migrate.source.schema.yml b/core/modules/migrate/config/schema/migrate.source.schema.yml
index d9101a0..f3dae0f 100644
--- a/core/modules/migrate/config/schema/migrate.source.schema.yml
+++ b/core/modules/migrate/config/schema/migrate.source.schema.yml
@@ -11,6 +11,3 @@ migrate.source.empty:
     provider:
       type: string
       label: 'Provider'
-    constants:
-      type: ignore
-      label: 'Constants'
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_system_site.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_system_site.yml
index c4920fa..78bb7ab 100644
--- a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_system_site.yml
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_system_site.yml
@@ -4,6 +4,8 @@ migration_tags:
   - Drupal 6
 source:
   plugin: variable
+  constants:
+    slash: '/'
   variables:
     - site_name
     - site_mail
@@ -17,9 +19,21 @@ process:
   name: site_name
   mail: site_mail
   slogan: site_slogan
-  'page/front': site_frontpage
-  'page/403': site_403
-  'page/404': site_404
+  'page/front':
+    plugin: concat
+    source:
+      - constants/slash
+      - site_frontpage
+  'page/403':
+    plugin: concat
+    source:
+      - constants/slash
+      - site_403
+  'page/404':
+    plugin: concat
+    source:
+      - constants/slash
+      - site_404
   weight_select_max: drupal_weight_select_max
   admin_compact_mode: admin_compact_mode
 destination:
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_url_alias.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_url_alias.yml
index a8579e9..454ded8 100644
--- a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_url_alias.yml
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_url_alias.yml
@@ -4,10 +4,20 @@ migration_tags:
   - Drupal 6
 source:
   plugin: d6_url_alias
+  constants:
+    slash: '/'
 
 process:
-  source: src
-  alias: dst
+  source:
+    plugin: concat
+    source:
+      - constants/slash
+      - src
+  alias:
+    plugin: concat
+    source:
+      - constants/slash
+      - dst
   langcode: language
 
 destination:
diff --git a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
index 2f23e0c..9fdf6d8 100644
--- a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
+++ b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
@@ -35,6 +35,9 @@ migrate.source.variable:
         status:
           type: boolean
           label: 'Status'
+        slash:
+          type: string
+          label: 'Slash'
 
 migrate.source.d6_comment:
   type: migrate_source_sql
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemSiteTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemSiteTest.php
index db1d68f..d543c20 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemSiteTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemSiteTest.php
@@ -40,9 +40,9 @@ public function testSystemSite() {
     $this->assertIdentical('site_name', $config->get('name'));
     $this->assertIdentical('site_mail@example.com', $config->get('mail'));
     $this->assertIdentical('Migrate rocks', $config->get('slogan'));
-    $this->assertIdentical('user', $config->get('page.403'));
-    $this->assertIdentical('page-not-found', $config->get('page.404'));
-    $this->assertIdentical('node', $config->get('page.front'));
+    $this->assertIdentical('/user', $config->get('page.403'));
+    $this->assertIdentical('/page-not-found', $config->get('page.404'));
+    $this->assertIdentical('/node', $config->get('page.front'));
     $this->assertIdentical(FALSE, $config->get('admin_compact_mode'));
   }
 
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php
index 7373557..572861d 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php
@@ -43,16 +43,16 @@ public function testUrlAlias() {
     $migration = entity_load('migration', 'd6_url_alias');
     // Test that the field exists.
     $conditions = array(
-      'source' => 'node/1',
-      'alias' => 'alias-one',
+      'source' => '/node/1',
+      'alias' => '/alias-one',
       'langcode' => 'en',
     );
     $path = \Drupal::service('path.alias_storage')->load($conditions);
     $this->assertNotNull($path, "Path alias for node/1 successfully loaded.");
     $this->assertIdentical($migration->getIdMap()->lookupDestinationID(array($path['pid'])), array('1'), "Test IdMap");
     $conditions = array(
-      'source' => 'node/2',
-      'alias' => 'alias-two',
+      'source' => '/node/2',
+      'alias' => '/alias-two',
       'langcode' => 'en',
     );
     $path = \Drupal::service('path.alias_storage')->load($conditions);
@@ -73,7 +73,7 @@ public function testUrlAlias() {
     $executable->import();
 
     $path = \Drupal::service('path.alias_storage')->load(array('pid' => $path['pid']));
-    $this->assertIdentical('new-url-alias', $path['alias']);
+    $this->assertIdentical('/new-url-alias', $path['alias']);
   }
 
 }
diff --git a/core/modules/node/src/Tests/NodeCreationTest.php b/core/modules/node/src/Tests/NodeCreationTest.php
index 7c1ef5f..5e8faaf 100644
--- a/core/modules/node/src/Tests/NodeCreationTest.php
+++ b/core/modules/node/src/Tests/NodeCreationTest.php
@@ -122,7 +122,7 @@ function testFailedPageCreation() {
    */
   function testUnpublishedNodeCreation() {
     // Set the front page to the test page.
-    $this->config('system.site')->set('page.front', 'test-page')->save();
+    $this->config('system.site')->set('page.front', '/test-page')->save();
 
     // Set "Basic page" content type to be unpublished by default.
     $fields = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
diff --git a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
index 95bd739..d8dec6a 100644
--- a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
@@ -64,7 +64,7 @@ function testPageCacheTags() {
     $block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', array(
       'visibility' => array(
         'request_path' => array(
-          'pages' => 'node/' . $node_2->id(),
+          'pages' => '/node/' . $node_2->id(),
         ),
       ),
     ));
diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php
index da8d5e4..244cd5b 100644
--- a/core/modules/page_cache/src/Tests/PageCacheTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTest.php
@@ -39,7 +39,7 @@ protected function setUp() {
 
     $this->config('system.site')
       ->set('name', 'Drupal')
-      ->set('page.front', 'test-page')
+      ->set('page.front', '/test-page')
       ->save();
   }
 
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 3148343..a9bd9b0 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -84,6 +84,6 @@ function path_entity_base_field_info(EntityTypeInterface $entity_type) {
  */
 function path_entity_translation_delete(EntityInterface $translation) {
   $path = $translation->urlInfo()->getInternalPath();
-  $conditions = array('source' => $path, 'langcode' => $translation->language()->getId());
+  $conditions = array('source' => '/' . $path, 'langcode' => $translation->language()->getId());
   \Drupal::service('path.alias_storage')->delete($conditions);
 }
diff --git a/core/modules/path/src/Controller/PathController.php b/core/modules/path/src/Controller/PathController.php
index cdb596d..4ee4d0d 100644
--- a/core/modules/path/src/Controller/PathController.php
+++ b/core/modules/path/src/Controller/PathController.php
@@ -88,10 +88,10 @@ public function adminOverview(Request $request) {
       $row = array();
       // @todo Should Path module store leading slashes? See
       //   https://www.drupal.org/node/2430593.
-      $row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput('/' . $data->source, array(
+      $row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput($data->source, array(
         'attributes' => array('title' => $data->alias),
       )));
-      $row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput('/' . $data->source, array(
+      $row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput($data->source, array(
         'alias' => TRUE,
         'attributes' => array('title' => $data->source),
       )));
diff --git a/core/modules/path/src/Form/PathFormBase.php b/core/modules/path/src/Form/PathFormBase.php
index c064a00..8c84841 100644
--- a/core/modules/path/src/Form/PathFormBase.php
+++ b/core/modules/path/src/Form/PathFormBase.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Path\AliasManagerInterface;
 use Drupal\Core\Path\AliasStorageInterface;
 use Drupal\Core\Path\PathValidatorInterface;
+use Drupal\Core\Routing\RequestContext;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -49,6 +50,13 @@
   protected $pathValidator;
 
   /**
+   * The request context.
+   *
+   * @var \Drupal\Core\Routing\RequestContext
+   */
+  protected $requestContext;
+
+  /**
    * Constructs a new PathController.
    *
    * @param \Drupal\Core\Path\AliasStorageInterface $alias_storage
@@ -57,11 +65,14 @@
    *   The path alias manager.
    * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
    *   The path validator.
+   * @param \Drupal\Core\Routing\RequestContext $request_context
+   *   The request context.
    */
-  public function __construct(AliasStorageInterface $alias_storage, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator) {
+  public function __construct(AliasStorageInterface $alias_storage, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator, RequestContext $request_context) {
     $this->aliasStorage = $alias_storage;
     $this->aliasManager = $alias_manager;
     $this->pathValidator = $path_validator;
+    $this->requestContext = $request_context;
   }
 
   /**
@@ -71,7 +82,8 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('path.alias_storage'),
       $container->get('path.alias_manager'),
-      $container->get('path.validator')
+      $container->get('path.validator'),
+      $container->get('router.request_context')
     );
   }
 
@@ -94,8 +106,8 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
       '#default_value' => $this->path['source'],
       '#maxlength' => 255,
       '#size' => 45,
-      '#description' => $this->t('Specify the existing path you wish to alias. For example: node/28, forum/1, taxonomy/term/1.'),
-      '#field_prefix' => $this->url('<none>', [], ['absolute' => TRUE]),
+      '#description' => $this->t('Specify the existing path you wish to alias. For example: /node/28, /forum/1, /taxonomy/term/1.'),
+      '#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
       '#required' => TRUE,
     );
     $form['alias'] = array(
@@ -104,8 +116,8 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
       '#default_value' => $this->path['alias'],
       '#maxlength' => 255,
       '#size' => 45,
-      '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "about" when writing an about page. Use a relative path.'),
-      '#field_prefix' => $this->url('<none>', [], ['absolute' => TRUE]),
+      '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "/about" when writing an about page. Use a relative path with a slash in front..'),
+      '#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
       '#required' => TRUE,
     );
 
@@ -151,8 +163,18 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $source = &$form_state->getValue('source');
     $source = $this->aliasManager->getPathByAlias($source);
     $alias = &$form_state->getValue('alias');
-    // Trim the submitted value of whitespace and slashes.
-    $alias = trim(trim($alias), " \\/");
+
+    // Trim the submitted value of whitespace and slashes. Ensure to not trim
+    // the slash on the left side.
+    $alias = rtrim(trim(trim($alias), ''), "\\/");
+
+    if ($source[0] !== '/') {
+      $form_state->setErrorByName('source', 'The source path has to start with a slash.');
+    }
+    if ($alias[0] !== '/') {
+      $form_state->setErrorByName('alias', 'The alias path has to start with a slash.');
+    }
+
     // Language is only set if language.module is enabled, otherwise save for all
     // languages.
     $langcode = $form_state->getValue('langcode', LanguageInterface::LANGCODE_NOT_SPECIFIED);
@@ -160,7 +182,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     if ($this->aliasStorage->aliasExists($alias, $langcode, $this->path['source'])) {
       $form_state->setErrorByName('alias', t('The alias %alias is already in use in this language.', array('%alias' => $alias)));
     }
-    if (!$this->pathValidator->isValid($source)) {
+    if (!$this->pathValidator->isValid(trim($source, '/'))) {
       $form_state->setErrorByName('source', t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $source)));
     }
   }
diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
index c06271d..61f5c5f 100644
--- a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
+++ b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
@@ -59,7 +59,7 @@ public function insert() {
     if ($this->alias) {
       $entity = $this->getEntity();
 
-      if ($path = \Drupal::service('path.alias_storage')->save($entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode())) {
+      if ($path = \Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode())) {
         $this->pid = $path['pid'];
       }
     }
@@ -76,7 +76,7 @@ public function update() {
     // Only save a non-empty alias.
     elseif ($this->alias) {
       $entity = $this->getEntity();
-      \Drupal::service('path.alias_storage')->save($entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode(), $this->pid);
+      \Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode(), $this->pid);
     }
   }
 
@@ -86,7 +86,7 @@ public function update() {
   public function delete() {
     // Delete all aliases associated with this entity.
     $entity = $this->getEntity();
-    \Drupal::service('path.alias_storage')->delete(array('source' => $entity->urlInfo()->getInternalPath()));
+    \Drupal::service('path.alias_storage')->delete(array('source' => '/' . $entity->urlInfo()->getInternalPath()));
   }
 
   /**
diff --git a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
index 03f15b3..07f1712 100644
--- a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
+++ b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
@@ -33,7 +33,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $entity = $items->getEntity();
     $path = array();
     if (!$entity->isNew()) {
-      $conditions = array('source' => $entity->urlInfo()->getInternalPath());
+      $conditions = array('source' => '/' . $entity->urlInfo()->getInternalPath());
       if ($items->getLangcode() != LanguageInterface::LANGCODE_NOT_SPECIFIED) {
         $conditions['langcode'] = $items->getLangcode();
       }
@@ -44,7 +44,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     }
     $path += array(
       'pid' => NULL,
-      'source' => !$entity->isNew() ? $entity->urlInfo()->getInternalPath() : NULL,
+      'source' => !$entity->isNew() ? '/' . $entity->urlInfo()->getInternalPath() : NULL,
       'alias' => '',
       'langcode' => $items->getLangcode(),
     );
@@ -58,7 +58,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       '#default_value' => $path['alias'],
       '#required' => $element['#required'],
       '#maxlength' => 255,
-      '#description' => $this->t('The alternative URL for this content. Use a relative path. For example, enter "about" for the about page.'),
+      '#description' => $this->t('The alternative URL for this content. Use a relative path. For example, enter "/about" for the about page.'),
     );
     $element['pid'] = array(
       '#type' => 'value',
@@ -85,7 +85,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    */
   public static function validateFormElement(array &$element, FormStateInterface $form_state) {
     // Trim the submitted value of whitespace and slashes.
-    $alias = trim(trim($element['alias']['#value']), " \\/");
+    $alias = rtrim(trim($element['alias']['#value']), " \\/");
     if (!empty($alias)) {
       $form_state->setValueForElement($element['alias'], $alias);
 
@@ -95,6 +95,10 @@ public static function validateFormElement(array &$element, FormStateInterface $
         $form_state->setError($element, t('The alias is already in use.'));
       }
     }
+
+    if ($alias && $alias[0] !== '/') {
+      $form_state->setError($element, t('The alias needs to start with a slash.'));
+    }
   }
 
   /**
diff --git a/core/modules/path/src/Tests/PathAdminTest.php b/core/modules/path/src/Tests/PathAdminTest.php
index 9073d7f..610b909 100644
--- a/core/modules/path/src/Tests/PathAdminTest.php
+++ b/core/modules/path/src/Tests/PathAdminTest.php
@@ -39,23 +39,23 @@ public function testPathFiltering() {
     $node3 = $this->drupalCreateNode();
 
     // Create aliases.
-    $alias1 = $this->randomMachineName(8);
+    $alias1 = '/' . $this->randomMachineName(8);
     $edit = array(
-      'source' => 'node/' . $node1->id(),
+      'source' => '/node/' . $node1->id(),
       'alias' => $alias1,
     );
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
-    $alias2 = $this->randomMachineName(8);
+    $alias2 = '/' . $this->randomMachineName(8);
     $edit = array(
-      'source' => 'node/' . $node2->id(),
+      'source' => '/node/' . $node2->id(),
       'alias' => $alias2,
     );
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
-    $alias3 = $this->randomMachineName(4) . '/' . $this->randomMachineName(4);
+    $alias3 = '/' . $this->randomMachineName(4) . '/' . $this->randomMachineName(4);
     $edit = array(
-      'source' => 'node/' . $node3->id(),
+      'source' => '/node/' . $node3->id(),
       'alias' => $alias3,
     );
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
diff --git a/core/modules/path/src/Tests/PathAliasTest.php b/core/modules/path/src/Tests/PathAliasTest.php
index c41b993..e4d07e2 100644
--- a/core/modules/path/src/Tests/PathAliasTest.php
+++ b/core/modules/path/src/Tests/PathAliasTest.php
@@ -39,8 +39,8 @@ function testPathCache() {
 
     // Create alias.
     $edit = array();
-    $edit['source'] = 'node/' . $node1->id();
-    $edit['alias'] = $this->randomMachineName(8);
+    $edit['source'] = '/node/' . $node1->id();
+    $edit['alias'] = '/' . $this->randomMachineName(8);
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
     // Check the path alias whitelist cache.
@@ -52,12 +52,12 @@ function testPathCache() {
     // created.
     \Drupal::cache('data')->deleteAll();
     // Make sure the path is not converted to the alias.
-    $this->drupalGet($edit['source'], array('alias' => TRUE));
+    $this->drupalGet(trim($edit['source'], '/'), array('alias' => TRUE));
     $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['source']), 'Cache entry was created.');
 
     // Visit the alias for the node and confirm a cache entry is created.
     \Drupal::cache('data')->deleteAll();
-    $this->drupalGet($edit['alias']);
+    $this->drupalGet(trim($edit['alias'], '/'));
     $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' .  $edit['source']), 'Cache entry was created.');
   }
 
@@ -70,8 +70,8 @@ function testAdminAlias() {
 
     // Create alias.
     $edit = array();
-    $edit['source'] = 'node/' . $node1->id();
-    $edit['alias'] = $this->randomMachineName(8);
+    $edit['source'] = '/node/' . $node1->id();
+    $edit['alias'] = '/' . $this->randomMachineName(8);
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
     // Confirm that the alias works.
@@ -83,7 +83,7 @@ function testAdminAlias() {
     $pid = $this->getPID($edit['alias']);
 
     $previous = $edit['alias'];
-    $edit['alias'] = "- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
+    $edit['alias'] = "/- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
       "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
       "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
     $this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
@@ -103,7 +103,7 @@ function testAdminAlias() {
     $node2 = $this->drupalCreateNode();
 
     // Set alias to second test node.
-    $edit['source'] = 'node/' . $node2->id();
+    $edit['source'] = '/node/' . $node2->id();
     // leave $edit['alias'] the same
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
@@ -121,8 +121,8 @@ function testAdminAlias() {
 
     // Create a really long alias.
     $edit = array();
-    $edit['source'] = 'node/' . $node1->id();
-    $alias = $this->randomMachineName(128);
+    $edit['source'] = '/node/' . $node1->id();
+    $alias = '/' . $this->randomMachineName(128);
     $edit['alias'] = $alias;
     // The alias is shortened to 50 characters counting the ellipsis.
     $truncated_alias = substr($alias, 0, 47);
@@ -136,23 +136,18 @@ function testAdminAlias() {
 
     // Create absolute path alias.
     $edit = array();
-    $edit['source'] = 'node/' . $node3->id();
-    $node3_alias = $this->randomMachineName(8);
-    $edit['alias'] = '/' . $node3_alias;
+    $edit['source'] = '/node/' . $node3->id();
+    $node3_alias = '/' . $this->randomMachineName(8);
+    $edit['alias'] = $node3_alias;
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
-    // Confirm that the alias was converted to a relative path.
-    $this->assertNoText($edit['alias'], 'The absolute alias was not found.');
-    // The 'relative' alias will always be found.
-    $this->assertText(trim($edit['alias'], '/'), 'The relative alias was found.');
-
     // Create fourth test node.
     $node4 = $this->drupalCreateNode();
 
     // Create alias with trailing slash.
     $edit = array();
-    $edit['source'] = 'node/' . $node4->id();
-    $node4_alias = $this->randomMachineName(8);
+    $edit['source'] = '/node/' . $node4->id();
+    $node4_alias = '/' . $this->randomMachineName(8);
     $edit['alias'] = $node4_alias . '/';
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
@@ -165,7 +160,7 @@ function testAdminAlias() {
     $pid = $this->getPID($node4_alias);
     $edit = [];
     $edit['alias'] = $node4_alias;
-    $edit['source'] = 'node/' . $node2->id();
+    $edit['source'] = '/node/' . $node2->id();
     $this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
     $this->assertText('The alias has been saved.');
     $this->drupalGet($edit['alias']);
@@ -177,10 +172,22 @@ function testAdminAlias() {
     $pid = $this->getPID($node3_alias);
     $edit = [];
     $edit['alias'] = $node4_alias;
-    $edit['source'] = 'node/' . $node3->id();
+    $edit['source'] = '/node/' . $node3->id();
     $this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
     $this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias'])));
 
+    // Create an alias without a starting slash.
+    $node5 = $this->drupalCreateNode();
+
+    $edit = array();
+    $edit['source'] = 'node/' . $node5->id();
+    $node5_alias = $this->randomMachineName(8);
+    $edit['alias'] = $node5_alias . '/';
+    $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
+
+    $this->assertUrl('admin/config/search/path/add');
+    $this->assertText('The source path has to start with a slash.');
+    $this->assertText('The alias path has to start with a slash.');
   }
 
   /**
@@ -192,7 +199,7 @@ function testNodeAlias() {
 
     // Create alias.
     $edit = array();
-    $edit['path[0][alias]'] = $this->randomMachineName(8);
+    $edit['path[0][alias]'] = '/' . $this->randomMachineName(8);
     $this->drupalPostForm('node/' . $node1->id() . '/edit', $edit, t('Save'));
 
     // Confirm that the alias works.
@@ -208,7 +215,7 @@ function testNodeAlias() {
 
     // Change alias to one containing "exotic" characters.
     $previous = $edit['path[0][alias]'];
-    $edit['path[0][alias]'] = "- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
+    $edit['path[0][alias]'] = "/- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
       "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
       "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
     $this->drupalPostForm('node/' . $node1->id() . '/edit', $edit, t('Save'));
@@ -257,7 +264,7 @@ function testNodeAlias() {
     $node4 = $this->drupalCreateNode();
 
     // Set its path alias to have a trailing slash.
-    $edit = array('path[0][alias]' => $this->randomMachineName(8) . '/');
+    $edit = array('path[0][alias]' => '/' . $this->randomMachineName(8) . '/');
     $this->drupalPostForm('node/' . $node4->id() . '/edit', $edit, t('Save'));
 
     // Confirm that the alias was converted to a relative path.
@@ -286,7 +293,7 @@ function testDuplicateNodeAlias() {
     // Create one node with a random alias.
     $node_one = $this->drupalCreateNode();
     $edit = array();
-    $edit['path[0][alias]'] = $this->randomMachineName();
+    $edit['path[0][alias]'] = '/' . $this->randomMachineName();
     $this->drupalPostForm('node/' . $node_one->id() . '/edit', $edit, t('Save'));
 
     // Now create another node and try to set the same alias.
diff --git a/core/modules/path/src/Tests/PathLanguageTest.php b/core/modules/path/src/Tests/PathLanguageTest.php
index 5351a80..67463f2 100644
--- a/core/modules/path/src/Tests/PathLanguageTest.php
+++ b/core/modules/path/src/Tests/PathLanguageTest.php
@@ -83,7 +83,7 @@ function testAliasTranslation() {
 
     // Edit the node to set language and path.
     $edit = array();
-    $edit['path[0][alias]'] = $english_alias;
+    $edit['path[0][alias]'] = '/' . $english_alias;
     $this->drupalPostForm('node/' . $english_node->id() . '/edit', $edit, t('Save'));
 
     // Confirm that the alias works.
@@ -98,7 +98,7 @@ function testAliasTranslation() {
     $edit['title[0][value]'] = $this->randomMachineName();
     $edit['body[0][value]'] = $this->randomMachineName();
     $french_alias = $this->randomMachineName();
-    $edit['path[0][alias]'] = $french_alias;
+    $edit['path[0][alias]'] = '/' . $french_alias;
     $this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
 
     // Clear the path lookup cache.
@@ -116,7 +116,7 @@ function testAliasTranslation() {
     $this->assertTrue($english_node->hasTranslation('fr'), 'Node found in database.');
 
     // Confirm that the alias works.
-    $this->drupalGet('fr/' . $edit['path[0][alias]']);
+    $this->drupalGet('fr' . $edit['path[0][alias]']);
     $this->assertText($english_node_french_translation->body->value, 'Alias for French translation works.');
 
     // Confirm that the alias is returned for the URL. Languages are cached on
@@ -174,22 +174,22 @@ function testAliasTranslation() {
     // The alias manager has an internal path lookup cache. Check to see that
     // it has the appropriate contents at this point.
     $this->container->get('path.alias_manager')->cacheClear();
-    $french_node_path = $this->container->get('path.alias_manager')->getPathByAlias($french_alias, 'fr');
-    $this->assertEqual($french_node_path, 'node/' . $english_node_french_translation->id(), 'Normal path works.');
+    $french_node_path = $this->container->get('path.alias_manager')->getPathByAlias('/' . $french_alias, 'fr');
+    $this->assertEqual($french_node_path, '/node/' . $english_node_french_translation->id(), 'Normal path works.');
     // Second call should return the same path.
-    $french_node_path = $this->container->get('path.alias_manager')->getPathByAlias($french_alias, 'fr');
-    $this->assertEqual($french_node_path, 'node/' . $english_node_french_translation->id(), 'Normal path is the same.');
+    $french_node_path = $this->container->get('path.alias_manager')->getPathByAlias('/' . $french_alias, 'fr');
+    $this->assertEqual($french_node_path, '/node/' . $english_node_french_translation->id(), 'Normal path is the same.');
 
     // Confirm that the alias works.
-    $french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $english_node_french_translation->id(), 'fr');
-    $this->assertEqual($french_node_alias, $french_alias, 'Alias works.');
+    $french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $english_node_french_translation->id(), 'fr');
+    $this->assertEqual($french_node_alias, '/' . $french_alias, 'Alias works.');
     // Second call should return the same alias.
-    $french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $english_node_french_translation->id(), 'fr');
-    $this->assertEqual($french_node_alias, $french_alias, 'Alias is the same.');
+    $french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $english_node_french_translation->id(), 'fr');
+    $this->assertEqual($french_node_alias, '/' . $french_alias, 'Alias is the same.');
 
     // Confirm that the alias is removed if the translation is deleted.
     $english_node->removeTranslation('fr');
     $english_node->save();
-    $this->assertFalse($this->container->get('path.alias_storage')->aliasExists($french_alias, 'fr'), 'Alias for French translation is removed when translation is deleted.');
+    $this->assertFalse($this->container->get('path.alias_storage')->aliasExists('/' . $french_alias, 'fr'), 'Alias for French translation is removed when translation is deleted.');
   }
 }
diff --git a/core/modules/path/src/Tests/PathLanguageUiTest.php b/core/modules/path/src/Tests/PathLanguageUiTest.php
index 39ea81f..55b3103 100644
--- a/core/modules/path/src/Tests/PathLanguageUiTest.php
+++ b/core/modules/path/src/Tests/PathLanguageUiTest.php
@@ -45,8 +45,8 @@ protected function setUp() {
   function testLanguageNeutralUrl() {
     $name = $this->randomMachineName(8);
     $edit = array();
-    $edit['source'] = 'admin/config/search/path';
-    $edit['alias'] = $name;
+    $edit['source'] = '/admin/config/search/path';
+    $edit['alias'] ='/' . $name;
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
     $this->drupalGet($name);
@@ -59,8 +59,8 @@ function testLanguageNeutralUrl() {
   function testDefaultLanguageUrl() {
     $name = $this->randomMachineName(8);
     $edit = array();
-    $edit['source'] = 'admin/config/search/path';
-    $edit['alias'] = $name;
+    $edit['source'] = '/admin/config/search/path';
+    $edit['alias'] = '/' . $name;
     $edit['langcode'] = 'en';
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
@@ -74,8 +74,8 @@ function testDefaultLanguageUrl() {
   function testNonDefaultUrl() {
     $name = $this->randomMachineName(8);
     $edit = array();
-    $edit['source'] = 'admin/config/search/path';
-    $edit['alias'] = $name;
+    $edit['source'] = '/admin/config/search/path';
+    $edit['alias'] = '/' . $name;
     $edit['langcode'] = 'fr';
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
diff --git a/core/modules/path/src/Tests/PathTaxonomyTermTest.php b/core/modules/path/src/Tests/PathTaxonomyTermTest.php
index 0d49c86..98372df 100644
--- a/core/modules/path/src/Tests/PathTaxonomyTermTest.php
+++ b/core/modules/path/src/Tests/PathTaxonomyTermTest.php
@@ -48,7 +48,7 @@ function testTermAlias() {
     $edit = array(
       'name[0][value]' => $this->randomMachineName(),
       'description[0][value]' => $description,
-      'path[0][alias]' => $this->randomMachineName(),
+      'path[0][alias]' => '/' . $this->randomMachineName(),
     );
     $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add', $edit, t('Save'));
     $tid = db_query("SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1", array(':name' => $edit['name[0][value]']))->fetchField();
@@ -65,15 +65,15 @@ function testTermAlias() {
 
     // Change the term's URL alias.
     $edit2 = array();
-    $edit2['path[0][alias]'] = $this->randomMachineName();
+    $edit2['path[0][alias]'] = '/' . $this->randomMachineName();
     $this->drupalPostForm('taxonomy/term/' . $tid . '/edit', $edit2, t('Save'));
 
     // Confirm that the changed alias works.
-    $this->drupalGet($edit2['path[0][alias]']);
+    $this->drupalGet(trim($edit2['path[0][alias]'], '/'));
     $this->assertText($description, 'Term can be accessed on changed URL alias.');
 
     // Confirm that the old alias no longer works.
-    $this->drupalGet($edit['path[0][alias]']);
+    $this->drupalGet(trim($edit['path[0][alias]'], '/'));
     $this->assertNoText($description, 'Old URL alias has been removed after altering.');
     $this->assertResponse(404, 'Old URL alias returns 404.');
 
@@ -83,7 +83,7 @@ function testTermAlias() {
     $this->drupalPostForm('taxonomy/term/' . $tid . '/edit', $edit3, t('Save'));
 
     // Confirm that the alias no longer works.
-    $this->drupalGet($edit2['path[0][alias]']);
+    $this->drupalGet(trim($edit2['path[0][alias]'], '/'));
     $this->assertNoText($description, 'Old URL alias has been removed after altering.');
     $this->assertResponse(404, 'Old URL alias returns 404.');
   }
diff --git a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
index 056a6a7..326fd72 100644
--- a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
+++ b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
@@ -34,8 +34,8 @@ public function testShortcutLinkAdd() {
 
     // Create an alias for the node so we can test aliases.
     $path = array(
-      'source' => 'node/' . $this->node->id(),
-      'alias' => $this->randomMachineName(8),
+      'source' => '/node/' . $this->node->id(),
+      'alias' => '/' . $this->randomMachineName(8),
     );
     $this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
 
diff --git a/core/modules/system/config/install/system.site.yml b/core/modules/system/config/install/system.site.yml
index 9eb22f3..d1ab8de 100644
--- a/core/modules/system/config/install/system.site.yml
+++ b/core/modules/system/config/install/system.site.yml
@@ -5,7 +5,7 @@ slogan: ''
 page:
   403: ''
   404: ''
-  front: user/login
+  front: /user/login
 admin_compact_mode: false
 weight_select_max: 100
 langcode: en
diff --git a/core/modules/system/src/Form/SiteInformationForm.php b/core/modules/system/src/Form/SiteInformationForm.php
index 71a0fbd..1b1e3a6 100644
--- a/core/modules/system/src/Form/SiteInformationForm.php
+++ b/core/modules/system/src/Form/SiteInformationForm.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Path\AliasManagerInterface;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Path\PathValidatorInterface;
+use Drupal\Core\Routing\RequestContext;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -34,6 +35,13 @@ class SiteInformationForm extends ConfigFormBase {
   protected $pathValidator;
 
   /**
+   * The request context.
+   *
+   * @var \Drupal\Core\Routing\RequestContext
+   */
+  protected $requestContext;
+
+  /**
    * Constructs a SiteInformationForm object.
    *
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
@@ -42,12 +50,15 @@ class SiteInformationForm extends ConfigFormBase {
    *   The path alias manager.
    * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
    *   The path validator.
+   * @param \Drupal\Core\Routing\RequestContext $request_context
+   *   The request context.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator) {
+  public function __construct(ConfigFactoryInterface $config_factory, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator, RequestContext $request_context) {
     parent::__construct($config_factory);
 
     $this->aliasManager = $alias_manager;
     $this->pathValidator = $path_validator;
+    $this->requestContext = $request_context;
   }
 
   /**
@@ -57,7 +68,8 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('config.factory'),
       $container->get('path.alias_manager'),
-      $container->get('path.validator')
+      $container->get('path.validator'),
+      $container->get('router.request_context')
     );
   }
 
@@ -114,14 +126,14 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => t('Front page'),
       '#open' => TRUE,
     );
-    $front_page = $site_config->get('page.front') != 'user/login' ? $this->aliasManager->getAliasByPath($site_config->get('page.front')) : '';
+    $front_page = $site_config->get('page.front') != '/user/login' ? $this->aliasManager->getAliasByPath($site_config->get('page.front')) : '';
     $form['front_page']['site_frontpage'] = array(
       '#type' => 'textfield',
       '#title' => t('Default front page'),
       '#default_value' => $front_page,
       '#size' => 40,
       '#description' => t('Optionally, specify a relative URL to display as the front page. Leave blank to display the default front page.'),
-      '#field_prefix' => $this->url('<none>', [], ['absolute' => TRUE]),
+      '#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
     );
     $form['error_page'] = array(
       '#type' => 'details',
@@ -134,7 +146,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $site_config->get('page.403'),
       '#size' => 40,
       '#description' => t('This page is displayed when the requested document is denied to the current user. Leave blank to display a generic "access denied" page.'),
-      '#field_prefix' => $this->url('<none>', [], ['absolute' => TRUE]),
     );
     $form['error_page']['site_404'] = array(
       '#type' => 'textfield',
@@ -142,7 +153,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $site_config->get('page.404'),
       '#size' => 40,
       '#description' => t('This page is displayed when no other content matches the requested document. Leave blank to display a generic "page not found" page.'),
-      '#field_prefix' => $this->url('<none>', [], ['absolute' => TRUE]),
     );
 
     return parent::buildForm($form, $form_state);
@@ -155,13 +165,17 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     // Check for empty front page path.
     if ($form_state->isValueEmpty('site_frontpage')) {
       // Set to default "user/login".
-      $form_state->setValueForElement($form['front_page']['site_frontpage'], 'user/login');
+      $form_state->setValueForElement($form['front_page']['site_frontpage'], '/user/login');
     }
     else {
       // Get the normal path of the front page.
       $form_state->setValueForElement($form['front_page']['site_frontpage'], $this->aliasManager->getPathByAlias($form_state->getValue('site_frontpage')));
     }
     // Validate front page path.
+    if (($value = $form_state->getValue('site_frontpage')) && $value[0] !== '/') {
+      $form_state->setErrorByName('site_frontpage', $this->t("The path '%path' has to start with a slash.", ['%path' => $form_state->getValue('site_frontpage')]));
+
+    }
     if (!$this->pathValidator->isValid($form_state->getValue('site_frontpage'))) {
       $form_state->setErrorByName('site_frontpage', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_frontpage'))));
     }
@@ -172,6 +186,12 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     if (!$form_state->isValueEmpty('site_404')) {
       $form_state->setValueForElement($form['error_page']['site_404'], $this->aliasManager->getPathByAlias($form_state->getValue('site_404')));
     }
+    if (($value = $form_state->getValue('site_403')) && $value[0] !== '/') {
+      $form_state->setErrorByName('site_403', $this->t("The path '%path' has to start with a slash.", ['%path' => $form_state->getValue('site_403')]));
+    }
+    if (($value = $form_state->getValue('site_404')) && $value[0] !== '/') {
+      $form_state->setErrorByName('site_404', $this->t("The path '%path' has to start with a slash.", ['%path' => $form_state->getValue('site_404')]));
+    }
     // Validate 403 error path.
     if (!$form_state->isValueEmpty('site_403') && !$this->pathValidator->isValid($form_state->getValue('site_403'))) {
       $form_state->setErrorByName('site_403', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_403'))));
diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php
index 56039bf..c6e51af 100644
--- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php
+++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php
@@ -138,11 +138,11 @@ public function build(RouteMatchInterface $route_match) {
     $exclude[$front] = TRUE;
     // /user is just a redirect, so skip it.
     // @todo Find a better way to deal with /user.
-    $exclude['user'] = TRUE;
+    $exclude['/user'] = TRUE;
     while (count($path_elements) > 1) {
       array_pop($path_elements);
       // Copy the path elements for up-casting.
-      $route_request = $this->getRequestForPath(implode('/', $path_elements), $exclude);
+      $route_request = $this->getRequestForPath('/' . implode('/', $path_elements), $exclude);
       if ($route_request) {
         $route_match = RouteMatch::createFromRequest($route_request);
         $access = $this->accessManager->check($route_match, $this->currentUser);
@@ -161,7 +161,7 @@ public function build(RouteMatchInterface $route_match) {
       }
 
     }
-    if ($path && $path != $front) {
+    if ($path && '/' . $path != $front) {
       // Add the Home link, except for the front page.
       $links[] = Link::createFromRoute($this->t('Home'), '<front>');
     }
@@ -172,7 +172,7 @@ public function build(RouteMatchInterface $route_match) {
    * Matches a path in the router.
    *
    * @param string $path
-   *   The request path.
+   *   The request path with a leading slash.
    * @param array $exclude
    *   An array of paths or system paths to skip.
    *
@@ -185,7 +185,7 @@ protected function getRequestForPath($path, array $exclude) {
     }
     // @todo Use the RequestHelper once https://www.drupal.org/node/2090293 is
     //   fixed.
-    $request = Request::create('/' . $path);
+    $request = Request::create($path);
     // Performance optimization: set a short accept header to reduce overhead in
     // AcceptHeaderMatcher when matching the request.
     $request->headers->set('Accept', 'text/html');
@@ -195,7 +195,7 @@ protected function getRequestForPath($path, array $exclude) {
       // This resolves to the front page, which we already add.
       return NULL;
     }
-    $this->currentPath->setPath('/' . $processed, $request);
+    $this->currentPath->setPath($processed, $request);
     // Attempt to match this path to provide a fully built request.
     try {
       $request->attributes->add($this->router->matchRequest($request));
diff --git a/core/modules/system/src/PathProcessor/PathProcessorFiles.php b/core/modules/system/src/PathProcessor/PathProcessorFiles.php
index 17730aa..50c6064 100644
--- a/core/modules/system/src/PathProcessor/PathProcessorFiles.php
+++ b/core/modules/system/src/PathProcessor/PathProcessorFiles.php
@@ -22,10 +22,10 @@ class PathProcessorFiles implements InboundPathProcessorInterface {
    * {@inheritdoc}
    */
   public function processInbound($path, Request $request) {
-    if (strpos($path, 'system/files/') === 0 && !$request->query->has('file')) {
-      $file_path = preg_replace('|^system\/files\/|', '', $path);
+    if (strpos($path, '/system/files/') === 0 && !$request->query->has('file')) {
+      $file_path = preg_replace('|^\/system\/files\/|', '', $path);
       $request->query->set('file', $file_path);
-      return 'system/files';
+      return '/system/files';
     }
     return $path;
   }
diff --git a/core/modules/system/src/Plugin/Condition/RequestPath.php b/core/modules/system/src/Plugin/Condition/RequestPath.php
index a309c58..876656c 100644
--- a/core/modules/system/src/Plugin/Condition/RequestPath.php
+++ b/core/modules/system/src/Plugin/Condition/RequestPath.php
@@ -153,7 +153,7 @@ public function evaluate() {
 
     $request = $this->requestStack->getCurrentRequest();
     // Compare the lowercase path alias (if any) and internal path.
-    $path = trim($this->currentPath->getPath($request), '/');
+    $path = rtrim($this->currentPath->getPath($request), '/');
     $path_alias = Unicode::strtolower($this->aliasManager->getAliasByPath($path));
 
     return $this->pathMatcher->matchPath($path_alias, $pages) || (($path != $path_alias) && $this->pathMatcher->matchPath($path, $pages));
diff --git a/core/modules/system/src/Tests/Path/AliasTest.php b/core/modules/system/src/Tests/Path/AliasTest.php
index 8eba1c9..4281905 100644
--- a/core/modules/system/src/Tests/Path/AliasTest.php
+++ b/core/modules/system/src/Tests/Path/AliasTest.php
@@ -51,8 +51,8 @@ function testCRUD() {
     }
 
     // Load alias by source path.
-    $loadedAlias = $aliasStorage->load(array('source' => 'node/1'));
-    $this->assertEqual($loadedAlias['alias'], 'alias_for_node_1_und', format_string('The last created alias loaded by default.'));
+    $loadedAlias = $aliasStorage->load(array('source' => '/node/1'));
+    $this->assertEqual($loadedAlias['alias'], '/alias_for_node_1_und', format_string('The last created alias loaded by default.'));
 
     //Update a few aliases
     foreach ($aliases as $alias) {
@@ -90,8 +90,8 @@ function testLookupPath() {
     // Test the situation where the source is the same for multiple aliases.
     // Start with a language-neutral alias, which we will override.
     $path = array(
-      'source' => "user/1",
-      'alias' => 'foo',
+      'source' => "/user/1",
+      'alias' => '/foo',
     );
 
     $aliasStorage->save($path['source'], $path['alias']);
@@ -100,8 +100,8 @@ function testLookupPath() {
 
     // Create a language specific alias for the default language (English).
     $path = array(
-      'source' => "user/1",
-      'alias' => "users/Dries",
+      'source' => "/user/1",
+      'alias' => "/users/Dries",
       'langcode' => 'en',
     );
     $aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
@@ -112,28 +112,28 @@ function testLookupPath() {
 
     // Create a language-neutral alias for the same path, again.
     $path = array(
-      'source' => "user/1",
-      'alias' => 'bar',
+      'source' => "/user/1",
+      'alias' => '/bar',
     );
     $aliasStorage->save($path['source'], $path['alias']);
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), "users/Dries", 'English alias still returned after entering a language-neutral alias.');
+    $this->assertEqual($aliasManager->getAliasByPath($path['source']), "/users/Dries", 'English alias still returned after entering a language-neutral alias.');
 
     // Create a language-specific (xx-lolspeak) alias for the same path.
     $path = array(
-      'source' => "user/1",
-      'alias' => 'LOL',
+      'source' => "/user/1",
+      'alias' => '/LOL',
       'langcode' => 'xx-lolspeak',
     );
     $aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), "users/Dries", 'English alias still returned after entering a LOLspeak alias.');
+    $this->assertEqual($aliasManager->getAliasByPath($path['source']), "/users/Dries", 'English alias still returned after entering a LOLspeak alias.');
     // The LOLspeak alias should be returned if we really want LOLspeak.
-    $this->assertEqual($aliasManager->getAliasByPath($path['source'], 'xx-lolspeak'), 'LOL', 'LOLspeak alias returned if we specify xx-lolspeak to the alias manager.');
+    $this->assertEqual($aliasManager->getAliasByPath($path['source'], 'xx-lolspeak'), '/LOL', 'LOLspeak alias returned if we specify xx-lolspeak to the alias manager.');
 
     // Create a new alias for this path in English, which should override the
     // previous alias for "user/1".
     $path = array(
-      'source' => "user/1",
-      'alias' => 'users/my-new-path',
+      'source' => "/user/1",
+      'alias' => '/users/my-new-path',
       'langcode' => 'en',
     );
     $aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
@@ -147,14 +147,14 @@ function testLookupPath() {
     $aliasStorage->delete(array('langcode' => 'en'));
     // Hook that clears cache is not executed with unit tests.
     $aliasManager->cacheClear();
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), 'bar', 'Path lookup falls back to recently created language-neutral alias.');
+    $this->assertEqual($aliasManager->getAliasByPath($path['source']), '/bar', 'Path lookup falls back to recently created language-neutral alias.');
 
     // Test the situation where the alias and language are the same, but
     // the source differs. The newer alias record should be returned.
-    $aliasStorage->save('user/2', 'bar');
+    $aliasStorage->save('/user/2', '/bar');
     // Hook that clears cache is not executed with unit tests.
     $aliasManager->cacheClear();
-    $this->assertEqual($aliasManager->getPathByAlias('bar'), 'user/2', 'Newer alias record is returned when comparing two LanguageInterface::LANGCODE_NOT_SPECIFIED paths with the same alias.');
+    $this->assertEqual($aliasManager->getPathByAlias('/bar'), '/user/2', 'Newer alias record is returned when comparing two LanguageInterface::LANGCODE_NOT_SPECIFIED paths with the same alias.');
   }
 
   /**
@@ -181,21 +181,21 @@ function testWhitelist() {
     $this->assertNull($whitelist->get($this->randomMachineName()));
 
     // Add an alias for user/1, user should get whitelisted now.
-    $aliasStorage->save('user/1', $this->randomMachineName());
+    $aliasStorage->save('/user/1', '/' . $this->randomMachineName());
     $aliasManager->cacheClear();
     $this->assertTrue($whitelist->get('user'));
     $this->assertNull($whitelist->get('admin'));
     $this->assertNull($whitelist->get($this->randomMachineName()));
 
     // Add an alias for admin, both should get whitelisted now.
-    $aliasStorage->save('admin/something', $this->randomMachineName());
+    $aliasStorage->save('/admin/something', '/' . $this->randomMachineName());
     $aliasManager->cacheClear();
     $this->assertTrue($whitelist->get('user'));
     $this->assertTrue($whitelist->get('admin'));
     $this->assertNull($whitelist->get($this->randomMachineName()));
 
     // Remove the user alias again, whitelist entry should be removed.
-    $aliasStorage->delete(array('source' => 'user/1'));
+    $aliasStorage->delete(array('source' => '/user/1'));
     $aliasManager->cacheClear();
     $this->assertNull($whitelist->get('user'));
     $this->assertTrue($whitelist->get('admin'));
diff --git a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
index 1b300d6..92438aa 100644
--- a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
+++ b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
@@ -53,23 +53,23 @@ public function dropTables(Connection $connection) {
   public function sampleUrlAliases() {
     return array(
       array(
-        'source' => 'node/1',
-        'alias' => 'alias_for_node_1_en',
+        'source' => '/node/1',
+        'alias' => '/alias_for_node_1_en',
         'langcode' => 'en'
       ),
       array(
-        'source' => 'node/2',
-        'alias' => 'alias_for_node_2_en',
+        'source' => '/node/2',
+        'alias' => '/alias_for_node_2_en',
         'langcode' => 'en'
       ),
       array(
-        'source' => 'node/1',
-        'alias' => 'alias_for_node_1_fr',
+        'source' => '/node/1',
+        'alias' => '/alias_for_node_1_fr',
         'langcode' => 'fr'
       ),
       array(
-        'source' => 'node/1',
-        'alias' => 'alias_for_node_1_und',
+        'source' => '/node/1',
+        'alias' => '/alias_for_node_1_und',
         'langcode' => 'und'
       )
     );
diff --git a/core/modules/system/src/Tests/Path/UrlAlterFunctionalTest.php b/core/modules/system/src/Tests/Path/UrlAlterFunctionalTest.php
index 2a6d796..d59d6b6 100644
--- a/core/modules/system/src/Tests/Path/UrlAlterFunctionalTest.php
+++ b/core/modules/system/src/Tests/Path/UrlAlterFunctionalTest.php
@@ -37,32 +37,32 @@ function testUrlAlter() {
     // Test a single altered path.
     $this->drupalGet("user/$name");
     $this->assertResponse('200', 'The user/username path gets resolved correctly');
-    $this->assertUrlOutboundAlter("user/$uid", "user/$name");
+    $this->assertUrlOutboundAlter("/user/$uid", "/user/$name");
 
     // Test that a path always uses its alias.
-    $path = array('source' => "user/$uid/test1", 'alias' => 'alias/test1');
+    $path = array('source' => "/user/$uid/test1", 'alias' => '/alias/test1');
     $this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
     $this->rebuildContainer();
-    $this->assertUrlInboundAlter('alias/test1', "user/$uid/test1");
-    $this->assertUrlOutboundAlter("user/$uid/test1", 'alias/test1');
+    $this->assertUrlInboundAlter('/alias/test1', "/user/$uid/test1");
+    $this->assertUrlOutboundAlter("/user/$uid/test1", '/alias/test1');
 
     // Test adding an alias via the UI.
-    $edit = array('source' => "user/$uid/edit", 'alias' => 'alias/test2');
+    $edit = array('source' => "/user/$uid/edit", 'alias' => '/alias/test2');
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
     $this->assertText(t('The alias has been saved.'));
     $this->drupalGet('alias/test2');
     $this->assertResponse('200', 'The path alias gets resolved correctly');
-    $this->assertUrlOutboundAlter("user/$uid/edit", 'alias/test2');
+    $this->assertUrlOutboundAlter("/user/$uid/edit", '/alias/test2');
 
     // Test a non-existent user is not altered.
     $uid++;
-    $this->assertUrlOutboundAlter("user/$uid", "user/$uid");
+    $this->assertUrlOutboundAlter("/user/$uid", "/user/$uid");
 
     // Test that 'forum' is altered to 'community' correctly, both at the root
     // level and for a specific existing forum.
     $this->drupalGet('community');
     $this->assertText('General discussion', 'The community path gets resolved correctly');
-    $this->assertUrlOutboundAlter('forum', 'community');
+    $this->assertUrlOutboundAlter('/forum', '/community');
     $forum_vid = $this->config('forum.settings')->get('vocabulary');
     $term_name = $this->randomMachineName();
     $term = entity_create('taxonomy_term', array(
@@ -72,7 +72,7 @@ function testUrlAlter() {
     $term->save();
     $this->drupalGet("community/" . $term->id());
     $this->assertText($term_name, 'The community/{tid} path gets resolved correctly');
-    $this->assertUrlOutboundAlter("forum/" . $term->id(), "community/" . $term->id());
+    $this->assertUrlOutboundAlter("/forum/" . $term->id(), "/community/" . $term->id());
   }
 
   /**
@@ -87,8 +87,8 @@ function testUrlAlter() {
    */
   protected function assertUrlOutboundAlter($original, $final) {
     // Test outbound altering.
-    $result = $this->container->get('url_generator')->generateFromPath($original);
-    $final = Url::fromUri('internal:/' . $final)->toString();
+    $result = $this->container->get('url_generator')->generateFromPath(ltrim($original, '/'));
+    $final = Url::fromUri('internal:' . $final)->toString();
     $this->assertIdentical($result, $final, format_string('Altered outbound URL %original, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result)));
   }
 
diff --git a/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php b/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php
index b5ac9ff..5d80493 100644
--- a/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php
+++ b/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php
@@ -86,7 +86,7 @@ public function testConditions() {
     // Get the request path condition and test and configure it to check against
     // different patterns and requests.
 
-    $pages = "my/pass/page\r\nmy/pass/page2\r\nfoo";
+    $pages = "/my/pass/page\r\n/my/pass/page2\r\n/foo";
 
     $request = Request::create('/my/pass/page2');
     $this->requestStack->push($request);
@@ -95,42 +95,42 @@ public function testConditions() {
     $condition = $this->pluginManager->createInstance('request_path');
     $condition->setConfig('pages', $pages);
 
-    $this->aliasManager->addAlias('my/pass/page2', 'my/pass/page2');
+    $this->aliasManager->addAlias('/my/pass/page2', '/my/pass/page2');
 
     $this->assertTrue($condition->execute(), 'The request path matches a standard path');
-    $this->assertEqual($condition->summary(), 'Return true on the following pages: my/pass/page, my/pass/page2, foo', 'The condition summary matches for a standard path');
+    $this->assertEqual($condition->summary(), 'Return true on the following pages: /my/pass/page, /my/pass/page2, /foo', 'The condition summary matches for a standard path');
 
     // Test an aliased path.
     $this->currentPath->setPath('/my/aliased/page', $request);
     $this->requestStack->pop();
     $this->requestStack->push($request);
 
-    $this->aliasManager->addAlias('my/aliased/page', 'my/pass/page');
+    $this->aliasManager->addAlias('/my/aliased/page', '/my/pass/page');
 
     $this->assertTrue($condition->execute(), 'The request path matches an aliased path');
-    $this->assertEqual($condition->summary(), 'Return true on the following pages: my/pass/page, my/pass/page2, foo', 'The condition summary matches for an aliased path');
+    $this->assertEqual($condition->summary(), 'Return true on the following pages: /my/pass/page, /my/pass/page2, /foo', 'The condition summary matches for an aliased path');
 
     // Test a wildcard path.
-    $this->aliasManager->addAlias('my/pass/page3', 'my/pass/page3');
+    $this->aliasManager->addAlias('/my/pass/page3', '/my/pass/page3');
     $this->currentPath->setPath('/my/pass/page3', $request);
     $this->requestStack->pop();
     $this->requestStack->push($request);
 
-    $condition->setConfig('pages', 'my/pass/*');
+    $condition->setConfig('pages', '/my/pass/*');
 
     $this->assertTrue($condition->evaluate(), 'The system_path my/pass/page3 passes for wildcard paths.');
-    $this->assertEqual($condition->summary(), 'Return true on the following pages: my/pass/*', 'The condition summary matches for a wildcard path');
+    $this->assertEqual($condition->summary(), 'Return true on the following pages: /my/pass/*', 'The condition summary matches for a wildcard path');
 
     // Test a missing path.
     $this->requestStack->pop();
     $this->requestStack->push($request);
     $this->currentPath->setPath('/my/fail/page4', $request);
 
-    $condition->setConfig('pages', 'my/pass/*');
+    $condition->setConfig('pages', '/my/pass/*');
 
-    $this->aliasManager->addAlias('my/fail/page4', 'my/fail/page4');
+    $this->aliasManager->addAlias('/my/fail/page4', '/my/fail/page4');
 
-    $this->assertFalse($condition->evaluate(), 'The system_path my/pass/page4 fails for a missing path.');
+    $this->assertFalse($condition->evaluate(), 'The system_path /my/pass/page4 fails for a missing path.');
 
   }
 }
diff --git a/core/modules/system/src/Tests/Routing/ContentNegotiationRoutingTest.php b/core/modules/system/src/Tests/Routing/ContentNegotiationRoutingTest.php
index ffc3157..98515b8 100644
--- a/core/modules/system/src/Tests/Routing/ContentNegotiationRoutingTest.php
+++ b/core/modules/system/src/Tests/Routing/ContentNegotiationRoutingTest.php
@@ -56,10 +56,10 @@ function testContentRouting() {
     /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
     $path_alias_storage = $this->container->get('path.alias_storage');
     // Alias with extension pointing to no extension/constant content-type.
-    $path_alias_storage->save('conneg/html', 'alias.html');
+    $path_alias_storage->save('/conneg/html', '/alias.html');
 
     // Alias with extension pointing to dynamic extension/linked content-type.
-    $path_alias_storage->save('conneg/html?_format=json', 'alias.json');
+    $path_alias_storage->save('/conneg/html?_format=json', '/alias.json');
 
     $tests = [
       // ['path', 'accept', 'content-type'],
@@ -102,7 +102,7 @@ function testContentRouting() {
       $accept_header = $test[1];
       $content_type = $test[2];
       $message = "Testing path:$path Accept:$accept_header Content-type:$content_type";
-      $request = Request::create($path);
+      $request = Request::create('/' . $path);
       if ($accept_header) {
         $request->headers->set('Accept', $accept_header);
       }
@@ -141,7 +141,7 @@ public function testFullNegotiation() {
       $accept_header = $test[1];
       $content_type = $test[2];
       $message = "Testing path:$path Accept:$accept_header Content-type:$content_type";
-      $request = Request::create($path);
+      $request = Request::create('/' . $path);
       $request->headers->set('Accept', $accept_header);
 
       /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $kernel */
diff --git a/core/modules/system/src/Tests/Routing/MockAliasManager.php b/core/modules/system/src/Tests/Routing/MockAliasManager.php
index 7ca6f9d..55f2ae2 100644
--- a/core/modules/system/src/Tests/Routing/MockAliasManager.php
+++ b/core/modules/system/src/Tests/Routing/MockAliasManager.php
@@ -55,6 +55,13 @@ class MockAliasManager implements AliasManagerInterface {
   public function addAlias($path, $alias, $path_language = NULL) {
     $language = $path_language ?: $this->defaultLanguage;
 
+    if ($path[0] !== '/') {
+      throw new \InvalidArgumentException('The path needs to start with a slash.');
+    }
+    if ($alias[0] !== '/') {
+      throw new \InvalidArgumentException('The alias needs to start with a slash.');
+    }
+
     $this->aliases[$path][$language] = $alias;
     $this->systemPaths[$alias][$language] = $path;
   }
diff --git a/core/modules/system/src/Tests/Routing/RouteProviderTest.php b/core/modules/system/src/Tests/Routing/RouteProviderTest.php
index 82d2028..74cbaa3 100644
--- a/core/modules/system/src/Tests/Routing/RouteProviderTest.php
+++ b/core/modules/system/src/Tests/Routing/RouteProviderTest.php
@@ -430,7 +430,7 @@ public function testRouteCaching() {
     // A path with a path alias.
     /** @var \Drupal\Core\Path\AliasStorageInterface $path_storage */
     $path_storage = \Drupal::service('path.alias_storage');
-    $path_storage->save('path/add/one', 'path/add-one');
+    $path_storage->save('/path/add/one', '/path/add-one');
     /** @var \Drupal\Core\Path\AliasManagerInterface $alias_manager */
     $alias_manager = \Drupal::service('path.alias_manager');
     $alias_manager->cacheClear();
diff --git a/core/modules/system/src/Tests/System/AccessDeniedTest.php b/core/modules/system/src/Tests/System/AccessDeniedTest.php
index 46984d0..0f37320 100644
--- a/core/modules/system/src/Tests/System/AccessDeniedTest.php
+++ b/core/modules/system/src/Tests/System/AccessDeniedTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\System;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\simpletest\WebTestBase;
 use Drupal\user\RoleInterface;
 
@@ -41,12 +42,20 @@ function testAccessDenied() {
     $this->assertText(t('Access denied'), 'Found the default 403 page');
     $this->assertResponse(403);
 
-    // Use a custom 403 page.
     $this->drupalLogin($this->adminUser);
+
+    // Set a custom 404 page without a starting slash.
     $edit = [
       'site_403' => 'user/' . $this->adminUser->id(),
     ];
     $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
+    $this->assertRaw(SafeMarkup::format("The path '%path' has to start with a slash.", ['%path' =>  $edit['site_403']]));
+
+    // Use a custom 403 page.
+    $edit = [
+      'site_403' => '/user/' . $this->adminUser->id(),
+    ];
+    $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
 
     // Enable the user login block.
     $this->drupalPlaceBlock('user_login_block', array('id' => 'login'));
@@ -73,7 +82,7 @@ function testAccessDenied() {
 
     // Log back in, set the custom 403 page to /user/login and remove the block
     $this->drupalLogin($this->adminUser);
-    $this->config('system.site')->set('page.403', 'user/login')->save();
+    $this->config('system.site')->set('page.403', '/user/login')->save();
     $edit = [
       'region' => -1,
     ];
diff --git a/core/modules/system/src/Tests/System/FrontPageTest.php b/core/modules/system/src/Tests/System/FrontPageTest.php
index cb9a13f..e5527d9 100644
--- a/core/modules/system/src/Tests/System/FrontPageTest.php
+++ b/core/modules/system/src/Tests/System/FrontPageTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\System;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -42,7 +43,7 @@ protected function setUp() {
     $this->nodePath = "node/" . $this->drupalCreateNode(array('promote' => 1))->id();
 
     // Configure 'node' as front page.
-    $this->config('system.site')->set('page.front', 'node')->save();
+    $this->config('system.site')->set('page.front', '/node')->save();
     // Enable front page logging in system_test.module.
     \Drupal::state()->set('system_test.front_page_output', 1);
   }
@@ -67,12 +68,17 @@ public function testDrupalFrontPage() {
     $this->assertNoText(t('On front page.'), 'Path is not the front page.');
 
     // Change the front page to an invalid path.
-    $edit = array('site_frontpage' => 'kittens');
+    $edit = array('site_frontpage' => '/kittens');
     $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
     $this->assertText(t("The path '@path' is either invalid or you do not have access to it.", array('@path' => $edit['site_frontpage'])));
 
+    // Change the front page to a path without a starting slash.
+    $edit = ['site_frontpage' => $this->nodePath];
+    $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
+    $this->assertRaw(SafeMarkup::format("The path '%path' has to start with a slash.", ['%path' =>  $edit['site_frontpage']]));
+
     // Change the front page to a valid path.
-    $edit['site_frontpage'] = $this->nodePath;
+    $edit['site_frontpage'] = '/' . $this->nodePath;
     $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
     $this->assertText(t('The configuration options have been saved.'), 'The front page path has been saved.');
 
diff --git a/core/modules/system/src/Tests/System/HtaccessTest.php b/core/modules/system/src/Tests/System/HtaccessTest.php
index 5254075..803491f 100644
--- a/core/modules/system/src/Tests/System/HtaccessTest.php
+++ b/core/modules/system/src/Tests/System/HtaccessTest.php
@@ -108,7 +108,7 @@ public function testFileAccess() {
     $node = $this->drupalCreateNode([
       'title' => 'This is a node',
       'type' => $type->id(),
-      'path' => 'test.php'
+      'path' => '/test.php'
     ]);
     $node->save();
     $this->drupalGet('test.php');
@@ -116,7 +116,7 @@ public function testFileAccess() {
     $this->assertText('This is a node');
 
     // Update node's alias to test.php/test.
-    $node->path = 'test.php/test';
+    $node->path = '/test.php/test';
     $node->save();
     $this->drupalGet('test.php/test');
     $this->assertResponse(200);
diff --git a/core/modules/system/src/Tests/System/PageNotFoundTest.php b/core/modules/system/src/Tests/System/PageNotFoundTest.php
index 03599b0..b7c0609 100644
--- a/core/modules/system/src/Tests/System/PageNotFoundTest.php
+++ b/core/modules/system/src/Tests/System/PageNotFoundTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\System;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\simpletest\WebTestBase;
 use Drupal\user\RoleInterface;
 
@@ -33,9 +34,16 @@ function testPageNotFound() {
     $this->drupalGet($this->randomMachineName(10));
     $this->assertText(t('Page not found'), 'Found the default 404 page');
 
+    // Set a custom 404 page without a starting slash.
+    $edit = [
+      'site_404' => 'user/' . $this->adminUser->id(),
+    ];
+    $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
+    $this->assertRaw(SafeMarkup::format("The path '%path' has to start with a slash.", ['%path' =>  $edit['site_404']]));
+
     // Use a custom 404 page.
     $edit = array(
-      'site_404' => 'user/' . $this->adminUser->id(),
+      'site_404' => '/user/' . $this->adminUser->id(),
     );
     $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration'));
 
diff --git a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php
index ade29a5..2aba280 100644
--- a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php
+++ b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php
@@ -29,7 +29,7 @@ protected function setUp() {
     parent::setUp();
 
     // Configure 'node' as front page.
-    $this->config('system.site')->set('page.front', 'node')->save();
+    $this->config('system.site')->set('page.front', '/node')->save();
 
     // Create a user allowed to access site in maintenance mode.
     $this->user = $this->drupalCreateUser(array('access site in maintenance mode'));
diff --git a/core/modules/system/src/Tests/Theme/ThemeTest.php b/core/modules/system/src/Tests/Theme/ThemeTest.php
index f6a2ef5..c2c0e0b 100644
--- a/core/modules/system/src/Tests/Theme/ThemeTest.php
+++ b/core/modules/system/src/Tests/Theme/ThemeTest.php
@@ -79,7 +79,7 @@ function testThemeDataTypes() {
   function testThemeSuggestions() {
     // Set the front page as something random otherwise the CLI
     // test runner fails.
-    $this->config('system.site')->set('page.front', 'nobody-home')->save();
+    $this->config('system.site')->set('page.front', '/nobody-home')->save();
     $args = array('node', '1', 'edit');
     $suggestions = theme_get_suggestions($args, 'page');
     $this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1', 'page__node__edit'), 'Found expected node edit page suggestions');
@@ -146,7 +146,7 @@ function testFrontPageThemeSuggestion() {
     $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'user.login');
     $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('/user/login'));
     \Drupal::requestStack()->push($request);
-    $this->config('system.site')->set('page.front', 'user/login')->save();
+    $this->config('system.site')->set('page.front', '/user/login')->save();
     $suggestions = theme_get_suggestions(array('user', 'login'), 'page');
     // Set it back to not annoy the batch runner.
     \Drupal::requestStack()->pop();
diff --git a/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php b/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php
index ecf1c95..bbe5f14 100644
--- a/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php
+++ b/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php
@@ -19,20 +19,20 @@ class PathProcessor implements InboundPathProcessorInterface {
    * Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
    */
   public function processInbound($path, Request $request) {
-    if (preg_match('!^user/([^/]+)(/.*)?!', $path, $matches)) {
+    if (preg_match('!^/user/([^/]+)(/.*)?!', $path, $matches)) {
       if ($account = user_load_by_name($matches[1])) {
         $matches += array(2 => '');
-        $path = 'user/' . $account->id() . $matches[2];
+        $path = '/user/' . $account->id() . $matches[2];
       }
     }
 
     // Rewrite community/ to forum/.
-    if ($path == 'community' || strpos($path, 'community/') === 0) {
-      $path = 'forum' . substr($path, 9);
+    if ($path == '/community' || strpos($path, '/community/') === 0) {
+      $path = '/forum' . substr($path, 9);
     }
 
-    if ($path == 'url-alter-test/bar') {
-      $path = 'url-alter-test/foo';
+    if ($path == '/url-alter-test/bar') {
+      $path = '/url-alter-test/foo';
     }
     return $path;
   }
diff --git a/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php b/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php
index 0b4e8ee..e30c1ca 100644
--- a/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php
+++ b/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php
@@ -23,20 +23,20 @@ class PathProcessorTest implements InboundPathProcessorInterface, OutboundPathPr
    */
   public function processInbound($path, Request $request) {
     // Rewrite user/username to user/uid.
-    if (preg_match('!^user/([^/]+)(/.*)?!', $path, $matches)) {
+    if (preg_match('!^/user/([^/]+)(/.*)?!', $path, $matches)) {
       if ($account = user_load_by_name($matches[1])) {
         $matches += array(2 => '');
-        $path = 'user/' . $account->id() . $matches[2];
+        $path = '/user/' . $account->id() . $matches[2];
       }
     }
 
     // Rewrite community/ to forum/.
-    if ($path == 'community' || strpos($path, 'community/') === 0) {
-      $path = 'forum' . substr($path, 9);
+    if ($path == '/community' || strpos($path, '/community/') === 0) {
+      $path = '/forum' . substr($path, 10);
     }
 
-    if ($path == 'url-alter-test/bar') {
-      $path = 'url-alter-test/foo';
+    if ($path == '/url-alter-test/bar') {
+      $path = '/url-alter-test/foo';
     }
     return $path;
   }
@@ -46,10 +46,10 @@ public function processInbound($path, Request $request) {
    */
   public function processOutbound($path, &$options = array(), Request $request = NULL, CacheableMetadata $cacheable_metadata = NULL) {
     // Rewrite user/uid to user/username.
-    if (preg_match('!^user/([0-9]+)(/.*)?!', $path, $matches)) {
+    if (preg_match('!^/user/([0-9]+)(/.*)?!', $path, $matches)) {
       if ($account = User::load($matches[1])) {
         $matches += array(2 => '');
-        $path = 'user/' . $account->getUsername() . $matches[2];
+        $path = '/user/' . $account->getUsername() . $matches[2];
         if ($cacheable_metadata) {
           $cacheable_metadata->addCacheTags($account->getCacheTags());
         }
@@ -57,8 +57,8 @@ public function processOutbound($path, &$options = array(), Request $request = N
     }
 
     // Rewrite forum/ to community/.
-    if ($path == 'forum' || strpos($path, 'forum/') === 0) {
-      $path = 'community' . substr($path, 5);
+    if ($path == '/forum' || strpos($path, '/forum/') === 0) {
+      $path = '/community' . substr($path, 5);
     }
     return $path;
   }
diff --git a/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php b/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
index b953072..3917c47 100644
--- a/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
+++ b/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
@@ -136,8 +136,8 @@ protected function isAdminPath(Request $request) {
           // Process the path as an inbound path. This will remove any language
           // prefixes and other path components that inbound processing would
           // clear out, so we can attempt to load the route clearly.
-          $path = $this->pathProcessorManager->processInbound(urldecode(trim($request->getPathInfo(), '/')), $request);
-          $attributes = $this->router->match('/' . $path);
+          $path = $this->pathProcessorManager->processInbound(urldecode(rtrim($request->getPathInfo(), '/')), $request);
+          $attributes = $this->router->match($path);
         }
         catch (ResourceNotFoundException $e) {
           return FALSE;
diff --git a/core/modules/user/src/Tests/UserAccountLinksTest.php b/core/modules/user/src/Tests/UserAccountLinksTest.php
index dac093b..0a6f3d7 100644
--- a/core/modules/user/src/Tests/UserAccountLinksTest.php
+++ b/core/modules/user/src/Tests/UserAccountLinksTest.php
@@ -31,7 +31,7 @@ protected function setUp() {
     parent::setUp();
     $this->drupalPlaceBlock('system_menu_block:account');
     // Make test-page default.
-    $this->config('system.site')->set('page.front', 'test-page')->save();
+    $this->config('system.site')->set('page.front', '/test-page')->save();
   }
 
   /**
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 2018d97..fbe962e 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -883,9 +883,7 @@ function template_preprocess_views_view_rss(&$variables) {
     // Compare the link to the default home page; if it's the default home page,
     // just use $base_url.
     $url_string = $url->setOptions($url_options)->toString();
-    // @todo Should page.front be stored with a leading slash? See
-    //   https://www.drupal.org/node/2430595.
-    if ($url_string === Url::fromUserInput('/' . $config->get('page.front'))->toString()) {
+    if ($url_string === Url::fromUserInput($config->get('page.front'))->toString()) {
       $url_string = Url::fromRoute('<front>')->setAbsolute()->toString();
     }
 
diff --git a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php b/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php
index a86b5f4..f1815a8 100644
--- a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php
+++ b/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php
@@ -117,7 +117,7 @@ function testWizardMixedDefaultOverriddenDisplays() {
     $this->drupalPlaceBlock("views_block:{$view['id']}-block_1", array(
       'visibility' => array(
         'request_path' => array(
-          'pages' => $view['page[path]'],
+          'pages' => '/' . $view['page[path]'],
           'negate' => TRUE,
         ),
       ),
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index 000ffa4..fd339b8 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -23,7 +23,7 @@ function standard_install() {
   \Drupal::service('entity.definition_update_manager')->applyUpdates();
 
   // Set front page to "node".
-  \Drupal::configFactory()->getEditable('system.site')->set('page.front', 'node')->save(TRUE);
+  \Drupal::configFactory()->getEditable('system.site')->set('page.front', '/node')->save(TRUE);
 
   // Allow visitor account creation with administrative approval.
   $user_settings = \Drupal::configFactory()->getEditable('user.settings');
diff --git a/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php b/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php
index 67bfed0..01290c4 100644
--- a/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php
@@ -88,7 +88,7 @@ protected function setUp() {
    * @covers ::getPathByAlias
    */
   public function testGetPathByAliasNoMatch() {
-    $alias = $this->randomMachineName();
+    $alias = '/' . $this->randomMachineName();
 
     $language = new Language(array('id' => 'en'));
 
@@ -159,7 +159,7 @@ public function testGetPathByAliasLangcode() {
   public function testGetAliasByPathWhitelist() {
     $path_part1 = $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
 
     $this->setUpCurrentLanguage();
 
@@ -184,7 +184,7 @@ public function testGetAliasByPathWhitelist() {
   public function testGetAliasByPathNoMatch() {
     $path_part1 = $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
 
     $language = $this->setUpCurrentLanguage();
 
@@ -221,7 +221,7 @@ public function testGetAliasByPathNoMatch() {
   public function testGetAliasByPathMatch() {
     $path_part1 = $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
     $alias = $this->randomMachineName();
 
     $language = $this->setUpCurrentLanguage();
@@ -257,9 +257,9 @@ public function testGetAliasByPathMatch() {
    * @covers ::writeCache
    */
   public function testGetAliasByPathCachedMatch() {
-    $path_part1 = $this->randomMachineName();
+    $path_part1 =  $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
     $alias = $this->randomMachineName();
 
     $language = $this->setUpCurrentLanguage();
@@ -306,7 +306,7 @@ public function testGetAliasByPathCachedMatch() {
   public function testGetAliasByPathCachedMissLanguage() {
     $path_part1 = $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
     $alias = $this->randomMachineName();
 
     $language = $this->setUpCurrentLanguage();
@@ -359,7 +359,7 @@ public function testGetAliasByPathCachedMissLanguage() {
   public function testGetAliasByPathCachedMissNoAlias() {
     $path_part1 = $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
     $cached_path = $this->randomMachineName();
     $cached_alias = $this->randomMachineName();
 
@@ -407,7 +407,7 @@ public function testGetAliasByPathCachedMissNoAlias() {
   public function testGetAliasByPathUncachedMissNoAlias() {
     $path_part1 = $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
     $cached_path = $this->randomMachineName();
     $cached_alias = $this->randomMachineName();
 
@@ -455,8 +455,8 @@ public function testGetAliasByPathUncachedMissNoAlias() {
    * @covers ::cacheClear
    */
   public function testCacheClear() {
-    $path = 'path';
-    $alias = 'alias';
+    $path = '/path';
+    $alias = '/alias';
     $language = $this->setUpCurrentLanguage();
     $this->aliasStorage->expects($this->exactly(2))
       ->method('lookupPathAlias')
@@ -497,7 +497,7 @@ public function testCacheClear() {
   public function testGetAliasByPathUncachedMissWithAlias() {
     $path_part1 = $this->randomMachineName();
     $path_part2 = $this->randomMachineName();
-    $path = $path_part1 . '/' . $path_part2;
+    $path = '/' . $path_part1 . '/' . $path_part2;
     $cached_path = $this->randomMachineName();
     $cached_no_alias_path = $this->randomMachineName();
     $cached_alias = $this->randomMachineName();
diff --git a/core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php b/core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php
index 75f7ca5..34d04c2 100644
--- a/core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php
+++ b/core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php
@@ -33,7 +33,7 @@ protected function setUp() {
     $config_factory_stub = $this->getConfigFactoryStub(
       array(
         'system.site' => array(
-          'page.front' => 'dummy',
+          'page.front' => '/dummy',
         ),
       )
     );
@@ -68,43 +68,43 @@ public function getMatchPathData() {
     return array(
       array(
         // Single absolute paths.
-        'example/1',
+        '/example/1',
         array(
-          'example/1' => TRUE,
-          'example/2' => FALSE,
-          'test' => FALSE,
+          '/example/1' => TRUE,
+          '/example/2' => FALSE,
+          '/test' => FALSE,
         ),
       ),
       array(
         // Single paths with wildcards.
-        'example/*',
+        '/example/*',
         array(
-          'example/1' => TRUE,
-          'example/2' => TRUE,
-          'example/3/edit' => TRUE,
-          'example/' => TRUE,
-          'example' => FALSE,
-          'test' => FALSE,
+          '/example/1' => TRUE,
+          '/example/2' => TRUE,
+          '/example/3/edit' => TRUE,
+          '/example/' => TRUE,
+          '/example' => FALSE,
+          '/test' => FALSE,
         ),
       ),
       array(
         // Single paths with multiple wildcards.
-        'node/*/revisions/*',
+        '/node/*/revisions/*',
         array(
-          'node/1/revisions/3' => TRUE,
-          'node/345/revisions/test' => TRUE,
-          'node/23/edit' => FALSE,
-          'test' => FALSE,
+          '/node/1/revisions/3' => TRUE,
+          '/node/345/revisions/test' => TRUE,
+          '/node/23/edit' => FALSE,
+          '/test' => FALSE,
         ),
       ),
       array(
         // Single paths with '<front>'.
         "<front>",
         array(
-          'dummy' => TRUE,
-          "dummy/" => FALSE,
-          "dummy/edit" => FALSE,
-          'node' => FALSE,
+          '/dummy' => TRUE,
+          "/dummy/" => FALSE,
+          "/dummy/edit" => FALSE,
+          '/node' => FALSE,
           '' => FALSE,
         ),
       ),
@@ -112,52 +112,52 @@ public function getMatchPathData() {
         // Paths with both '<front>' and wildcards (should not work).
         "<front>/*",
         array(
-          'dummy' => FALSE,
-          'dummy/' => FALSE,
-          'dummy/edit' => FALSE,
-          'node/12' => FALSE,
-          '' => FALSE,
+          '/dummy' => FALSE,
+          '/dummy/' => FALSE,
+          '/dummy/edit' => FALSE,
+          '/node/12' => FALSE,
+          '/' => FALSE,
         ),
       ),
       array(
         // Multiple paths with the \n delimiter.
-        "node/*\nnode/*/edit",
+        "/node/*\n/node/*/edit",
         array(
-          'node/1' => TRUE,
-          'node/view' => TRUE,
-          'node/32/edit' => TRUE,
-          'node/delete/edit' => TRUE,
-          'node/50/delete' => TRUE,
-          'test/example' => FALSE,
+          '/node/1' => TRUE,
+          '/node/view' => TRUE,
+          '/node/32/edit' => TRUE,
+          '/node/delete/edit' => TRUE,
+          '/node/50/delete' => TRUE,
+          '/test/example' => FALSE,
         ),
       ),
       array(
         // Multiple paths with the \r delimiter.
-        "user/*\rexample/*",
+        "/user/*\r/example/*",
         array(
-          'user/1' => TRUE,
-          'example/1' => TRUE,
-          'user/1/example/1' => TRUE,
-          'user/example' => TRUE,
-          'test/example' => FALSE,
-          'user' => FALSE,
-          'example' => FALSE,
+          '/user/1' => TRUE,
+          '/example/1' => TRUE,
+          '/user/1/example/1' => TRUE,
+          '/user/example' => TRUE,
+          '/test/example' => FALSE,
+          '/user' => FALSE,
+          '/example' => FALSE,
         ),
       ),
       array(
         // Multiple paths with the \r\n delimiter.
-        "test\r\n<front>",
+        "/test\r\n<front>",
         array(
-          'test' => TRUE,
-          'dummy' => TRUE,
-          'example' => FALSE,
+          '/test' => TRUE,
+          '/dummy' => TRUE,
+          '/example' => FALSE,
         ),
       ),
       array(
         // Test existing regular expressions (should be escaped).
         '[^/]+?/[0-9]',
         array(
-          'test/1' => FALSE,
+          '/test/1' => FALSE,
           '[^/]+?/[0-9]' => TRUE,
         ),
       ),
diff --git a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
index 548f80f..b0acb12 100644
--- a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
+++ b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
@@ -179,8 +179,8 @@ public function testIsValidWithPathAlias() {
       ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]);
     $this->pathProcessor->expects($this->once())
       ->method('processInbound')
-      ->with('path-alias', $this->anything())
-      ->willReturn('test-path');
+      ->with('/path-alias', $this->anything())
+      ->willReturn('/test-path');
 
     $this->assertTrue($this->pathValidator->isValid('path-alias'));
   }
diff --git a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
index 8a84c18..025b293 100644
--- a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
+++ b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
@@ -103,11 +103,11 @@ function testProcessInbound() {
 
     $system_path_map = array(
       // Set up one proper alias that can be resolved to a system path.
-      array('foo', NULL, 'user/1'),
+      array('/foo', NULL, '/user/1'),
       // Passing in anything else should return the same string.
-      array('fr/foo', NULL, 'fr/foo'),
-      array('fr', NULL, 'fr'),
-      array('user/login', NULL, 'user/login'),
+      array('/fr/foo', NULL, '/fr/foo'),
+      array('/fr', NULL, '/fr'),
+      array('/user/login', NULL, '/user/login'),
     );
 
     $alias_manager->expects($this->any())
@@ -119,7 +119,7 @@ function testProcessInbound() {
     $config_factory_stub = $this->getConfigFactoryStub(
       array(
         'system.site' => array(
-          'page.front' => 'user/login'
+          'page.front' => '/user/login'
         ),
         'language.negotiation' => array(
           'url' => array(
@@ -169,16 +169,16 @@ function testProcessInbound() {
     }
 
     // Test resolving the French homepage using the incorrect processor order.
-    $test_path = 'fr';
+    $test_path = '/fr';
     $request = Request::create($test_path);
     $processed = $processor_manager->processInbound($test_path, $request);
-    $this->assertEquals('', $processed, 'Processing in the incorrect order fails to resolve the system path from the empty path');
+    $this->assertEquals('/', $processed, 'Processing in the incorrect order fails to resolve the system path from the empty path');
 
     // Test resolving an existing alias using the incorrect processor order.
-    $test_path = 'fr/foo';
+    $test_path = '/fr/foo';
     $request = Request::create($test_path);
     $processed = $processor_manager->processInbound($test_path, $request);
-    $this->assertEquals('foo', $processed, 'Processing in the incorrect order fails to resolve the system path from an alias');
+    $this->assertEquals('/foo', $processed, 'Processing in the incorrect order fails to resolve the system path from an alias');
 
     // Now create a new processor manager and add the processors, this time in
     // the correct order.
@@ -194,15 +194,15 @@ function testProcessInbound() {
     }
 
     // Test resolving the French homepage using the correct processor order.
-    $test_path = 'fr';
+    $test_path = '/fr';
     $request = Request::create($test_path);
     $processed = $processor_manager->processInbound($test_path, $request);
-    $this->assertEquals('user/login', $processed, 'Processing in the correct order resolves the system path from the empty path.');
+    $this->assertEquals('/user/login', $processed, 'Processing in the correct order resolves the system path from the empty path.');
 
     // Test resolving an existing alias using the correct processor order.
-    $test_path = 'fr/foo';
+    $test_path = '/fr/foo';
     $request = Request::create($test_path);
     $processed = $processor_manager->processInbound($test_path, $request);
-    $this->assertEquals('user/1', $processed, 'Processing in the correct order resolves the system path from an alias.');
+    $this->assertEquals('/user/1', $processed, 'Processing in the correct order resolves the system path from an alias.');
   }
 }
diff --git a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
index 2bdba78..57edd51 100644
--- a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
@@ -159,12 +159,12 @@ protected function setUp() {
   public function aliasManagerCallback() {
     $args = func_get_args();
     switch($args[0]) {
-      case 'test/one':
-        return 'hello/world';
-      case 'test/two/5':
-        return 'goodbye/cruel/world';
-      case '<front>':
-        return '';
+      case '/test/one':
+        return '/hello/world';
+      case '/test/two/5':
+        return '/goodbye/cruel/world';
+      case '/<front>':
+        return '/';
       default:
         return $args[0];
     }
