 core/lib/Drupal/Core/Form/ConfirmFormHelper.php                      | 5 +++++
 core/lib/Drupal/Core/Render/RenderCache.php                          | 3 +++
 .../tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php    | 2 +-
 core/modules/book/src/Tests/BookTest.php                             | 4 +++-
 core/modules/book/tests/modules/book_test.module                     | 1 +
 core/modules/page_cache/src/Tests/PageCacheTest.php                  | 2 +-
 core/modules/path/src/Tests/PathAliasTest.php                        | 4 ++++
 core/modules/search/src/Controller/SearchController.php              | 1 +
 core/modules/system/src/EventSubscriber/ConfigCacheTag.php           | 4 ++--
 .../tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php     | 5 +++++
 .../system/tests/modules/paramconverter_test/src/TestControllers.php | 4 +++-
 core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php          | 5 +++++
 12 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
index fab63f9..5446a3d 100644
--- a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
+++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
@@ -52,6 +52,11 @@ public static function buildCancelLink(ConfirmFormInterface $form, Request $requ
       '#title' => $form->getCancelText(),
       '#attributes' => ['class' => ['button']],
       '#url' => $url,
+      '#cache' => [
+        'contexts' => [
+          'url.query_args:destination',
+        ],
+      ],
     ];
   }
 
diff --git a/core/lib/Drupal/Core/Render/RenderCache.php b/core/lib/Drupal/Core/Render/RenderCache.php
index 880fca3..b7fb4f6 100644
--- a/core/lib/Drupal/Core/Render/RenderCache.php
+++ b/core/lib/Drupal/Core/Render/RenderCache.php
@@ -16,6 +16,9 @@
 
 /**
  * Wraps the caching logic for the render caching system.
+ *
+ * @todo Refactor this out into a generic service capable of cache redirects,
+ *   and let RenderCache use that. https://www.drupal.org/node/2551419
  */
 class RenderCache implements RenderCacheInterface {
 
diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php
index 873a77b..eb9ee56 100644
--- a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php
+++ b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestAccessBlock.php
@@ -63,7 +63,7 @@ public static function create(ContainerInterface $container, array $configuratio
    * {@inheritdoc}
    */
   protected function blockAccess(AccountInterface $account) {
-    return $this->state->get('test_block_access', FALSE) ? AccessResult::allowed() : AccessResult::forbidden();
+    return $this->state->get('test_block_access', FALSE) ? AccessResult::allowed()->setCacheMaxAge(0) : AccessResult::forbidden()->setCacheMaxAge(0);
   }
 
   /**
diff --git a/core/modules/book/src/Tests/BookTest.php b/core/modules/book/src/Tests/BookTest.php
index b0235c4..b530265 100644
--- a/core/modules/book/src/Tests/BookTest.php
+++ b/core/modules/book/src/Tests/BookTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\book\Tests;
 
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\simpletest\WebTestBase;
 use Drupal\user\RoleInterface;
@@ -124,11 +125,12 @@ public function testBookNavigationCacheContext() {
 
     // Enable the debug output.
     \Drupal::state()->set('book_test.debug_book_navigation_cache_context', TRUE);
+    Cache::invalidateTags(['book_test.debug_book_navigation_cache_context']);
 
     $this->drupalLogin($this->bookAuthor);
 
     // On non-node route.
-    $this->drupalGet('');
+    $this->drupalGet($this->adminUser->urlInfo());
     $this->assertRaw('[route.book_navigation]=book.none');
 
     // On non-book node route.
diff --git a/core/modules/book/tests/modules/book_test.module b/core/modules/book/tests/modules/book_test.module
index 2f868a4..939e756 100644
--- a/core/modules/book/tests/modules/book_test.module
+++ b/core/modules/book/tests/modules/book_test.module
@@ -15,6 +15,7 @@
  * Implements hook_page_attachments().
  */
 function book_test_page_attachments(array &$page) {
+  $page['#cache']['tags'][] = 'book_test.debug_book_navigation_cache_context';
   if (\Drupal::state()->get('book_test.debug_book_navigation_cache_context', FALSE)) {
     drupal_set_message(\Drupal::service('cache_contexts_manager')->convertTokensToKeys(['route.book_navigation'])->getKeys()[0]);
   }
diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php
index e97a1b4..18a6dfd 100644
--- a/core/modules/page_cache/src/Tests/PageCacheTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTest.php
@@ -399,7 +399,7 @@ public function testFormImmutability() {
     // that implementation.
     \Drupal::state()->set('page_cache_bypass_form_immutability', TRUE);
     \Drupal::moduleHandler()->resetImplementations();
-    \Drupal::cache('render')->deleteAll();
+    Cache::invalidateTags(['rendered']);
 
     $this->drupalGet('page_cache_form_test_immutability');
 
diff --git a/core/modules/path/src/Tests/PathAliasTest.php b/core/modules/path/src/Tests/PathAliasTest.php
index e4d07e2..651c11f 100644
--- a/core/modules/path/src/Tests/PathAliasTest.php
+++ b/core/modules/path/src/Tests/PathAliasTest.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\path\Tests;
 
+use Drupal\Core\Cache\Cache;
+
 /**
  * Add, edit, delete, and change alias and verify its consistency in the
  * database.
@@ -57,6 +59,8 @@ function testPathCache() {
 
     // Visit the alias for the node and confirm a cache entry is created.
     \Drupal::cache('data')->deleteAll();
+    // @todo Remove this once https://www.drupal.org/node/2480077 lands.
+    Cache::invalidateTags(['rendered']);
     $this->drupalGet(trim($edit['alias'], '/'));
     $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' .  $edit['source']), 'Cache entry was created.');
   }
diff --git a/core/modules/search/src/Controller/SearchController.php b/core/modules/search/src/Controller/SearchController.php
index e775531..4d839d1 100644
--- a/core/modules/search/src/Controller/SearchController.php
+++ b/core/modules/search/src/Controller/SearchController.php
@@ -75,6 +75,7 @@ public function view(Request $request, SearchPageInterface $entity) {
 
     // Build the form first, because it may redirect during the submit,
     // and we don't want to build the results based on last time's request.
+    $build['#cache']['contexts'][] = 'url.query_args:keys';
     if ($request->query->has('keys')) {
       $keys = trim($request->get('keys'));
       $plugin->setSearch($keys, $request->query->all(), $request->attributes->all());
diff --git a/core/modules/system/src/EventSubscriber/ConfigCacheTag.php b/core/modules/system/src/EventSubscriber/ConfigCacheTag.php
index 0482a74..640a6f0 100644
--- a/core/modules/system/src/EventSubscriber/ConfigCacheTag.php
+++ b/core/modules/system/src/EventSubscriber/ConfigCacheTag.php
@@ -60,8 +60,8 @@ public function onSave(ConfigCrudEvent $event) {
       $this->cacheTagsInvalidator->invalidateTags(['route_match', 'rendered']);
     }
 
-    // Global theme settings.
-    if ($event->getConfig()->getName() === 'system.theme.global') {
+    // Theme configuration and global theme settings.
+    if (in_array($event->getConfig()->getName(), ['system.theme', 'system.theme.global'])) {
       $this->cacheTagsInvalidator->invalidateTags(['rendered']);
     }
 
diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php
index 8d40948..90ddb62 100644
--- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php
+++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php
@@ -40,6 +40,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#value' => 'Submit',
     );
 
+    // This is a POST form with multiple steps that does not transition from one
+    // step to the next via POST requests, but via GET requests, because it uses
+    // Batch API to advance through the steps.
+    $form['#cache']['max-age'] = 0;
+
     return $form;
   }
 
diff --git a/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php b/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php
index 1e8e2f4..327a8d5 100644
--- a/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php
+++ b/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php
@@ -25,6 +25,8 @@ public function testNodeSetParent(NodeInterface $node, NodeInterface $parent) {
   }
 
   public function testEntityLanguage(NodeInterface $node) {
-    return ['#markup' => $node->label()];
+    $build = ['#markup' => $node->label()];
+    \Drupal::service('renderer')->addCacheableDependency($build, $node);
+    return $build;
   }
 }
diff --git a/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php b/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php
index 1dc65a9..27743cb 100644
--- a/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php
@@ -33,6 +33,7 @@ public function testCancelLinkTitle() {
 
     $link = ConfirmFormHelper::buildCancelLink($form, new Request());
     $this->assertSame($cancel_text, $link['#title']);
+    $this->assertSame(['contexts' => ['url.query_args:destination']], $link['#cache']);
   }
 
   /**
@@ -49,6 +50,7 @@ public function testCancelLinkRoute() {
       ->will($this->returnValue($cancel_route));
     $link = ConfirmFormHelper::buildCancelLink($form, new Request());
     $this->assertEquals(Url::fromRoute($route_name), $link['#url']);
+    $this->assertSame(['contexts' => ['url.query_args:destination']], $link['#cache']);
   }
 
   /**
@@ -64,6 +66,7 @@ public function testCancelLinkRouteWithParams() {
       ->will($this->returnValue($expected));
     $link = ConfirmFormHelper::buildCancelLink($form, new Request());
     $this->assertEquals($expected, $link['#url']);
+    $this->assertSame(['contexts' => ['url.query_args:destination']], $link['#cache']);
   }
 
   /**
@@ -86,6 +89,7 @@ public function testCancelLinkRouteWithUrl() {
       ->will($this->returnValue($cancel_route));
     $link = ConfirmFormHelper::buildCancelLink($form, new Request());
     $this->assertSame($cancel_route, $link['#url']);
+    $this->assertSame(['contexts' => ['url.query_args:destination']], $link['#cache']);
   }
 
   /**
@@ -112,6 +116,7 @@ public function testCancelLinkDestination($destination) {
 
     $link = ConfirmFormHelper::buildCancelLink($form, new Request($query));
     $this->assertSame($url, $link['#url']);
+    $this->assertSame(['contexts' => ['url.query_args:destination']], $link['#cache']);
   }
 
   /**
