diff --git a/core/lib/Drupal/Core/Cache/CacheableRedirectResponse.php b/core/lib/Drupal/Core/Cache/CacheableRedirectResponse.php
new file mode 100644
index 0000000..7d949ff
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheableRedirectResponse.php
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\CacheableResponse.
+ */
+
+namespace Drupal\Core\Cache;
+
+use Symfony\Component\HttpFoundation\RedirectResponse;
+
+/**
+ * A RedirectResponse that contains and can expose cacheability metadata.
+ *
+ * Supports Drupal's caching concepts: cache tags for invalidation and cache
+ * contexts for variations.
+ *
+ * @see \Drupal\Core\Cache\Cache
+ * @see \Drupal\Core\Cache\CacheableMetadata
+ * @see \Drupal\Core\Cache\CacheableResponseTrait
+ */
+class CacheableRedirectResponse extends RedirectResponse implements CacheableResponseInterface {
+
+  use CacheableResponseTrait;
+
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php
index 51ebbc2..84bdda1 100644
--- a/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\Core\EventSubscriber;
 
-use Symfony\Component\HttpFoundation\RedirectResponse;
+use Drupal\Core\Cache\CacheableRedirectResponse;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -39,7 +39,7 @@ public function redirect(GetResponseEvent $event) {
       if ($qs) {
         $qs = '?' . $qs;
       }
-      $event->setResponse(new RedirectResponse($request->getUriForPath($path) . $qs));
+      $event->setResponse(new CacheableRedirectResponse($request->getUriForPath($path) . $qs));
     }
   }
 
diff --git a/core/lib/Drupal/Core/Routing/UrlGeneratorTrait.php b/core/lib/Drupal/Core/Routing/UrlGeneratorTrait.php
index 5a63105..5f1aa7d 100644
--- a/core/lib/Drupal/Core/Routing/UrlGeneratorTrait.php
+++ b/core/lib/Drupal/Core/Routing/UrlGeneratorTrait.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\Core\Routing;
 
-use Symfony\Component\HttpFoundation\RedirectResponse;
+use Drupal\Core\Cache\CacheableRedirectResponse;
 
 /**
  * Wrapper methods for the Url Generator.
@@ -35,8 +35,8 @@
    * @return string
    *   The generated URL for the given route.
    */
-  protected function url($route_name, $route_parameters = array(), $options = array()) {
-    return $this->getUrlGenerator()->generateFromRoute($route_name, $route_parameters, $options);
+  protected function url($route_name, $route_parameters = array(), $options = array(), $collect_bubbleable_metadata = FALSE) {
+    return $this->getUrlGenerator()->generateFromRoute($route_name, $route_parameters, $options, $collect_bubbleable_metadata);
   }
 
   /**
@@ -57,8 +57,9 @@ protected function url($route_name, $route_parameters = array(), $options = arra
    */
   protected function redirect($route_name, array $route_parameters = [], array $options = [], $status = 302) {
     $options['absolute'] = TRUE;
-    $url = $this->url($route_name, $route_parameters, $options);
-    return new RedirectResponse($url, $status);
+    $url = $this->url($route_name, $route_parameters, $options, TRUE);
+    $response = new CacheableRedirectResponse($url->getGeneratedUrl(), $status);
+    return $response->addCacheableDependency($url);
   }
 
   /**
diff --git a/core/modules/locale/src/Controller/LocaleController.php b/core/modules/locale/src/Controller/LocaleController.php
index 0638b08..4402889 100644
--- a/core/modules/locale/src/Controller/LocaleController.php
+++ b/core/modules/locale/src/Controller/LocaleController.php
@@ -37,7 +37,7 @@ public function checkTranslation() {
       return batch_process('admin/reports/translations');
     }
 
-    return $this->redirect('locale.translate_status');
+    return new RedirectResponse($thus->url('locale.translate_status', [], ['absolute' => TRUE]));
   }
 
   /**
diff --git a/core/modules/node/src/Controller/NodeController.php b/core/modules/node/src/Controller/NodeController.php
index 299d253..f1dacca 100644
--- a/core/modules/node/src/Controller/NodeController.php
+++ b/core/modules/node/src/Controller/NodeController.php
@@ -80,15 +80,24 @@ public function addPage() {
       }
     }
 
+    // Ensure that the response is invalidated whenever a node type is
+    // added/removed.
+    $cache_tags = array('config:node_type_list');
+
     // Bypass the node/add listing if only one content type is available.
     if (count($content) == 1) {
       $type = array_shift($content);
-      return $this->redirect('node.add', array('node_type' => $type->id()));
+      $response = $this->redirect('node.add', array('node_type' => $type->id()));
+      $response->getCacheableMetadata()->setCacheTags($cache_tags);
+      return $response;
     }
 
     return array(
       '#theme' => 'node_add_list',
       '#content' => $content,
+      '#cache' => array(
+        '#tags' => $cache_tags,
+      ),
     );
   }
 
diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml
index 6eb709f..8c00c45 100644
--- a/core/modules/user/user.routing.yml
+++ b/core/modules/user/user.routing.yml
@@ -12,6 +12,8 @@ user.logout:
     _controller: '\Drupal\user\Controller\UserController::logout'
   requirements:
     _user_is_logged_in: 'TRUE'
+  options:
+    no_cache: TRUE
 
 user.admin_index:
   path: '/admin/config/people'
diff --git a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTraitTest.php b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTraitTest.php
index 2bb4466..d7d64f9 100644
--- a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTraitTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTraitTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Tests\Core\Routing;
 
+use Drupal\Core\GeneratedUrl;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -36,12 +37,12 @@ public function testGetUrlGenerator() {
    */
   public function testRedirect() {
     $route_name = 'some_route_name';
-    $generated_url = 'some/generated/url';
+    $generated_url = (new GeneratedUrl())->setGeneratedUrl('some/generated/url');
 
     $url_generator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
     $url_generator->expects($this->once())
       ->method('generateFromRoute')
-      ->with($route_name, [], ['absolute' => TRUE])
+      ->with($route_name, [], ['absolute' => TRUE], TRUE)
       ->willReturn($generated_url);
 
     $url_generator_trait_object = $this->getMockForTrait('Drupal\Core\Routing\UrlGeneratorTrait');
@@ -52,7 +53,7 @@ public function testRedirect() {
 
     $result = $url_generator_method->invoke($url_generator_trait_object, $route_name);
     $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $result);
-    $this->assertSame($generated_url, $result->getTargetUrl());
+    $this->assertSame($generated_url->getGeneratedUrl(), $result->getTargetUrl());
   }
 
 }
