diff --git a/core/lib/Drupal/Core/PathProcessor/PathProcessorAlias.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorAlias.php
index b85737f..4c9c79c 100644
--- a/core/lib/Drupal/Core/PathProcessor/PathProcessorAlias.php
+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorAlias.php
@@ -32,7 +32,7 @@ public function __construct(AliasManagerInterface $alias_manager) {
    * {@inheritdoc}
    */
   public function processInbound($path, Request $request) {
-    $path = $this->aliasManager->getPathByAlias($path);
+    $path = $this->aliasManager->getPathByAlias($path, $request->getLocale());
     return $path;
   }
 
diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
index 7436a3f..35c5dc7 100644
--- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
@@ -110,6 +110,7 @@ public function processInbound($path, Request $request) {
         if (isset($config['prefixes'][$language->getId()]) && $config['prefixes'][$language->getId()] == $prefix) {
           // Rebuild $path with the language removed.
           $path = '/' . implode('/', $parts);
+          $request->setLocale($prefix);
           break;
         }
       }
diff --git a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
index b0928b0..47fffd4 100644
--- a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
+++ b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
@@ -173,10 +173,14 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
     $element = [];
     $entity = $items->getEntity();
     $settings = $this->getSettings();
+    $language = \Drupal::languageManager()->getLanguage($langcode);
 
     foreach ($items as $delta => $item) {
       // By default use the full URL as the link text.
       $url = $this->buildUrl($item);
+      if (!$item->getFieldDefinition()->get('translatable')) {
+        $url->setOption('language', $language);
+      }
       $link_title = $url->toString();
 
       // If the title field value is available, use it for the link text.
diff --git a/core/tests/Drupal/FunctionalTests/Core/Path/AliasManagerTest.php b/core/tests/Drupal/FunctionalTests/Core/Path/AliasManagerTest.php
new file mode 100644
index 0000000..ee2ac77
--- /dev/null
+++ b/core/tests/Drupal/FunctionalTests/Core/Path/AliasManagerTest.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace Drupal\FunctionalTests\Core\Path;
+
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\Tests\BrowserTestBase;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Tests the functionality of AliasManager in KernelTestBase tests.
+ *
+ * @group path
+ */
+class AliasManagerTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['system', 'node', 'path', 'language'];
+
+  /**
+   * Tests aliased route caching in language context.
+   *
+   * Tests whether an aliased path match will be found in the context of the
+   * current language and that it will be cached properly.
+   */
+  public function testAliasedRouteCache() {
+    $this->loginAdmin();
+    $this->createContentType(['type' => 'page']);
+    ConfigurableLanguage::createFromLangcode('ro')->save();
+
+    // Confirm that the additional language was created.
+    $this->assertEquals(2, count(\Drupal::languageManager()->getLanguages()), 'There are two languages.');
+
+    $node = $this->createAliasedNode('/test-page', 'en');
+
+    // Confirm that alias was created and saved.
+    $path = $this->container->get('path.alias_storage')
+      ->load(['alias' => '/test-page']);
+    $this->assertTrue($path, 'Alias was created.');
+
+    // Confirm that the node default route exists.
+    $request = Request::create('/node/' . $node->id());
+    $routes = $this->container->get('router.route_provider')
+      ->getRouteCollectionForRequest($request);
+    $this->assertEquals(1, $routes->count());
+
+    // Confirm that the route for the aliased path is found in default language.
+    $routes = $this->container->get('router.route_provider')
+      ->getRouteCollectionForRequest(Request::create('/test-page'));
+    $this->assertEquals(1, $routes->count());
+
+    // Confirm that the page can be reached through alias.
+    $this->drupalGet('/test-page');
+    $this->assertSession()->statusCodeEquals(200);
+
+    // Begin proving the issue.
+    // Ensure that the current request is on the language on which the test page
+    // is not translated.
+    $this->resetAll();
+    $this->createAliasedNode('/ro-page', 'ro');
+    \Drupal::requestStack()->push(Request::create('/ro/ro-page'));
+    \Drupal::languageManager()->reset();
+    $this->assertEquals('ro', \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId());
+
+    // Prove that the route won't be found in the current language. This happens
+    // because the alias manager won't find the alias in the current language
+    // context. In this step the route provider will cache that there are no
+    // routes for this request. With link rendering this happens right after the
+    // processInbound call in the PathValidator::getPathAttributes.
+    $routes = $this->container->get('router.route_provider')
+      ->getRouteCollectionForRequest(Request::create('/test-page'));
+    $this->assertEquals(1, $routes->count(), 'Route for the alias in ro language was not found.');
+
+    // Remove the manually added request.
+    \Drupal::requestStack()->pop();
+    \Drupal::languageManager()->reset();
+
+    // Prove that the aliased page is not found.
+    $this->drupalGet('/test-page');
+    $this->assertSession()->statusCodeEquals(200);
+  }
+
+  /**
+   * Creates and aliased node.
+   *
+   * @param string $alias
+   *    The path alias.
+   * @param string $langcode
+   *    The language code of the node.
+   *
+   * @return \Drupal\node\NodeInterface
+   *    Created node.
+   */
+  protected function createAliasedNode($alias, $langcode) {
+    return $this->drupalCreateNode([
+      'type' => 'page',
+      'title' => 'Test page',
+      'path' => [
+        'alias' => $alias
+      ],
+      'langcode' => $langcode,
+    ]);
+  }
+
+  /**
+   * Creates an admin user and logs it in.
+   */
+  protected function loginAdmin() {
+    $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'access content'));
+    $this->drupalLogin($admin_user);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorAliasTest.php b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorAliasTest.php
index 0473d79..449f9a0 100644
--- a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorAliasTest.php
+++ b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorAliasTest.php
@@ -42,8 +42,8 @@ public function testProcessInbound() {
     $this->aliasManager->expects($this->exactly(2))
       ->method('getPathByAlias')
       ->will($this->returnValueMap([
-        ['urlalias', NULL, 'internal-url'],
-        ['url', NULL, 'url'],
+        ['urlalias', 'en', 'internal-url'],
+        ['url', 'en', 'url'],
       ]));
 
     $request = Request::create('/urlalias');
diff --git a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
index 57dfbfa..f973e37 100644
--- a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
+++ b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
@@ -98,12 +98,17 @@ public function testProcessInbound() {
       ->getMock();
 
     $system_path_map = [
-      // Set up one proper alias that can be resolved to a system path.
-      ['/foo', NULL, '/user/1'],
+      // Set up one proper alias for each language that can be resolved to a
+      // system path.
+      ['/foo', 'en', '/user/1'],
+      ['/foo', 'fr', '/user/1'],
       // Passing in anything else should return the same string.
-      ['/fr/foo', NULL, '/fr/foo'],
-      ['/fr', NULL, '/fr'],
-      ['/user/login', NULL, '/user/login'],
+      ['/fr/foo', 'en', '/fr/foo'],
+      ['/fr/foo', 'fr', '/fr/foo'],
+      ['/fr', 'en', '/fr'],
+      ['/fr', 'fr', '/fr'],
+      ['/user/login', 'en', '/user/login'],
+      ['/user/login', 'fr', '/user/login'],
     ];
 
     $alias_manager->expects($this->any())
