diff --git a/core/core.services.yml b/core/core.services.yml
index e39252d..dd5c4fd 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -16,6 +16,7 @@ parameters:
       tags: []
   factory.keyvalue:
     default: keyvalue.database
+  http.response.debug_cacheability_headers: false
   factory.keyvalue.expirable:
     default: keyvalue.expirable.database
   filter_protocols:
@@ -1070,7 +1071,7 @@ services:
     class: Drupal\Core\EventSubscriber\FinishResponseSubscriber
     tags:
       - { name: event_subscriber }
-    arguments: ['@language_manager', '@config.factory', '@page_cache_request_policy', '@page_cache_response_policy', '@cache_contexts_manager']
+    arguments: ['@language_manager', '@config.factory', '@page_cache_request_policy', '@page_cache_response_policy', '@cache_contexts_manager', '%http.response.debug_cacheability_headers%']
   response_generator_subscriber:
     class: Drupal\Core\EventSubscriber\ResponseGeneratorSubscriber
     tags:
diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
index b625f59..a373688 100644
--- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -62,6 +62,13 @@ class FinishResponseSubscriber implements EventSubscriberInterface {
   protected $cacheContexts;
 
   /**
+   * Whether to send cacheability headers for debugging purposes.
+   *
+   * @var bool
+   */
+  protected $debugCacheabilityHeaders = FALSE;
+
+  /**
    * Constructs a FinishResponseSubscriber object.
    *
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
@@ -74,13 +81,16 @@ class FinishResponseSubscriber implements EventSubscriberInterface {
    *   A policy rule determining the cacheability of a response.
    * @param \Drupal\Core\Cache\Context\CacheContextsManager $cache_contexts_manager
    *   The cache contexts manager service.
+   * @param bool $http_response_debug_cacheability_headers
+   *   (optional) Whether to send cacheability headers for debugging purposes.
    */
-  public function __construct(LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory, RequestPolicyInterface $request_policy, ResponsePolicyInterface $response_policy, CacheContextsManager $cache_contexts_manager) {
+  public function __construct(LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory, RequestPolicyInterface $request_policy, ResponsePolicyInterface $response_policy, CacheContextsManager $cache_contexts_manager, $http_response_debug_cacheability_headers = FALSE) {
     $this->languageManager = $language_manager;
     $this->config = $config_factory->get('system.performance');
     $this->requestPolicy = $request_policy;
     $this->responsePolicy = $response_policy;
     $this->cacheContextsManager = $cache_contexts_manager;
+    $this->debugCacheabilityHeaders = $http_response_debug_cacheability_headers;
   }
 
   /**
@@ -130,11 +140,13 @@ public function onRespond(FilterResponseEvent $event) {
       return;
     }
 
-    // Expose the cache contexts and cache tags associated with this page in a
-    // X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags header respectively.
-    $response_cacheability = $response->getCacheableMetadata();
-    $response->headers->set('X-Drupal-Cache-Tags', implode(' ', $response_cacheability->getCacheTags()));
-    $response->headers->set('X-Drupal-Cache-Contexts', implode(' ', $this->cacheContextsManager->optimizeTokens($response_cacheability->getCacheContexts())));
+    if ($this->debugCacheabilityHeaders) {
+      // Expose the cache contexts and cache tags associated with this page in a
+      // X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags header respectively.
+      $response_cacheability = $response->getCacheableMetadata();
+      $response->headers->set('X-Drupal-Cache-Tags', implode(' ', $response_cacheability->getCacheTags()));
+      $response->headers->set('X-Drupal-Cache-Contexts', implode(' ', $this->cacheContextsManager->optimizeTokens($response_cacheability->getCacheContexts())));
+    }
 
     $is_cacheable = ($this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW) && ($this->responsePolicy->check($response, $request) !== ResponsePolicyInterface::DENY);
 
diff --git a/core/modules/aggregator/src/Tests/AggregatorRenderingTest.php b/core/modules/aggregator/src/Tests/AggregatorRenderingTest.php
index 63a7e97..659b578 100644
--- a/core/modules/aggregator/src/Tests/AggregatorRenderingTest.php
+++ b/core/modules/aggregator/src/Tests/AggregatorRenderingTest.php
@@ -26,6 +26,8 @@ class AggregatorRenderingTest extends AggregatorTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalPlaceBlock('page_title_block');
   }
 
diff --git a/core/modules/block/src/Tests/BlockInstallTest.php b/core/modules/block/src/Tests/BlockInstallTest.php
index 84819e6..f736396 100644
--- a/core/modules/block/src/Tests/BlockInstallTest.php
+++ b/core/modules/block/src/Tests/BlockInstallTest.php
@@ -17,6 +17,8 @@
 class BlockInstallTest extends WebTestBase {
 
   public function testCacheTagInvalidationUponInstallation() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Warm the page cache.
     $this->drupalGet('');
     $this->assertNoText('Powered by Drupal');
diff --git a/core/modules/block/src/Tests/BlockSystemBrandingTest.php b/core/modules/block/src/Tests/BlockSystemBrandingTest.php
index a78f675..3da983e 100644
--- a/core/modules/block/src/Tests/BlockSystemBrandingTest.php
+++ b/core/modules/block/src/Tests/BlockSystemBrandingTest.php
@@ -32,6 +32,8 @@ protected function setUp() {
       ->save();
     // Add the system branding block to the page.
     $this->drupalPlaceBlock('system_branding_block', array('region' => 'header', 'id' => 'site-branding'));
+
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
   }
 
   /**
diff --git a/core/modules/block/src/Tests/Views/DisplayBlockTest.php b/core/modules/block/src/Tests/Views/DisplayBlockTest.php
index f7b3ffe..2b59fb7 100644
--- a/core/modules/block/src/Tests/Views/DisplayBlockTest.php
+++ b/core/modules/block/src/Tests/Views/DisplayBlockTest.php
@@ -241,6 +241,8 @@ public function testViewsBlockForm() {
    * Tests the actual rendering of the views block.
    */
   public function testBlockRendering() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create a block and set a custom title.
     $block = $this->drupalPlaceBlock('views_block:test_view_block-block_1', array('label' => 'test_view_block-block_1:1', 'views_label' => 'Custom title'));
     $this->drupalGet('');
@@ -272,6 +274,8 @@ public function testBlockRendering() {
    * Tests the various testcases of empty block rendering.
    */
   public function testBlockEmptyRendering() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $url = new Url('test_page_test.test_page');
     // Remove all views_test_data entries.
     \Drupal::database()->truncate('views_test_data')->execute();
diff --git a/core/modules/book/src/Tests/BookTest.php b/core/modules/book/src/Tests/BookTest.php
index b1c9fa3..3b992f9 100644
--- a/core/modules/book/src/Tests/BookTest.php
+++ b/core/modules/book/src/Tests/BookTest.php
@@ -170,6 +170,8 @@ function testEmptyBook() {
    * Tests book functionality through node interfaces.
    */
   function testBook() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create new book.
     $nodes = $this->createBook();
     $book = $this->book;
diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/src/Tests/CommentAnonymousTest.php
index b7e5bd8..2709508 100644
--- a/core/modules/comment/src/Tests/CommentAnonymousTest.php
+++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php
@@ -19,6 +19,8 @@ class CommentAnonymousTest extends CommentTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Enable anonymous and authenticated user comments.
     user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array(
       'access comments',
diff --git a/core/modules/comment/src/Tests/CommentRssTest.php b/core/modules/comment/src/Tests/CommentRssTest.php
index 2a87859..af1b2dc 100644
--- a/core/modules/comment/src/Tests/CommentRssTest.php
+++ b/core/modules/comment/src/Tests/CommentRssTest.php
@@ -34,6 +34,8 @@ class CommentRssTest extends CommentTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Setup the rss view display.
     EntityViewDisplay::create([
       'status' => TRUE,
diff --git a/core/modules/config/src/Tests/CacheabilityMetadataConfigOverrideIntegrationTest.php b/core/modules/config/src/Tests/CacheabilityMetadataConfigOverrideIntegrationTest.php
index 22d0b11..88361e8 100644
--- a/core/modules/config/src/Tests/CacheabilityMetadataConfigOverrideIntegrationTest.php
+++ b/core/modules/config/src/Tests/CacheabilityMetadataConfigOverrideIntegrationTest.php
@@ -30,6 +30,8 @@ class CacheabilityMetadataConfigOverrideIntegrationTest extends WebTestBase {
   public function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // @todo If our block does not contain any content then the cache context
     //   is not bubbling up and the test fails. Remove this line once the cache
     //   contexts are properly set. See https://www.drupal.org/node/2529980.
diff --git a/core/modules/contact/src/Tests/ContactPersonalTest.php b/core/modules/contact/src/Tests/ContactPersonalTest.php
index d133240..908634a 100644
--- a/core/modules/contact/src/Tests/ContactPersonalTest.php
+++ b/core/modules/contact/src/Tests/ContactPersonalTest.php
@@ -109,6 +109,8 @@ function testSendPersonalContactMessage() {
    * Tests access to the personal contact form.
    */
   function testPersonalContactAccess() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Test allowed access to admin user's contact form.
     $this->drupalLogin($this->webUser);
     $this->drupalGet('user/' . $this->adminUser->id() . '/contact');
diff --git a/core/modules/contact/src/Tests/ContactSitewideTest.php b/core/modules/contact/src/Tests/ContactSitewideTest.php
index 39cd34a..8083ef4 100644
--- a/core/modules/contact/src/Tests/ContactSitewideTest.php
+++ b/core/modules/contact/src/Tests/ContactSitewideTest.php
@@ -47,6 +47,8 @@ protected function setUp() {
    * Tests configuration options and the site-wide contact form.
    */
   function testSiteWideContact() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create and login administrative user.
     $admin_user = $this->drupalCreateUser(array(
       'access site-wide contact form',
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
index 9ed2e46..d498bb9 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
@@ -58,6 +58,8 @@
    * Tests the basic translation UI.
    */
   function testTranslationUI() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->doTestBasicTranslation();
     $this->doTestTranslationOverview();
     $this->doTestOutdatedStatus();
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
index b602be0..b9147c3 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
@@ -36,6 +36,7 @@ class ContentTranslationWorkflowsTest extends ContentTranslationTestBase {
   protected function setUp() {
     parent::setUp();
     $this->setupEntity();
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
   }
 
   /**
diff --git a/core/modules/forum/src/Tests/ForumIndexTest.php b/core/modules/forum/src/Tests/ForumIndexTest.php
index e84a3eb..e26dc25 100644
--- a/core/modules/forum/src/Tests/ForumIndexTest.php
+++ b/core/modules/forum/src/Tests/ForumIndexTest.php
@@ -29,6 +29,8 @@ protected function setUp() {
     // Create a test user.
     $web_user = $this->drupalCreateUser(['create forum content', 'edit own forum content', 'edit any forum content', 'administer nodes', 'administer forums']);
     $this->drupalLogin($web_user);
+
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
   }
 
   /**
diff --git a/core/modules/forum/src/Tests/ForumTest.php b/core/modules/forum/src/Tests/ForumTest.php
index 974e400..ef3784b 100644
--- a/core/modules/forum/src/Tests/ForumTest.php
+++ b/core/modules/forum/src/Tests/ForumTest.php
@@ -123,6 +123,8 @@ protected function setUp() {
    * Tests forum functionality through the admin and user interfaces.
    */
   function testForum() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     //Check that the basic forum install creates a default forum topic
     $this->drupalGet('/forum');
     // Look for the "General discussion" default forum
diff --git a/core/modules/history/src/Tests/HistoryTest.php b/core/modules/history/src/Tests/HistoryTest.php
index 3340f1a..3953b0f 100644
--- a/core/modules/history/src/Tests/HistoryTest.php
+++ b/core/modules/history/src/Tests/HistoryTest.php
@@ -41,6 +41,8 @@ class HistoryTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
 
     $this->user = $this->drupalCreateUser(array('create page content', 'access content'));
diff --git a/core/modules/image/src/Tests/ImageFieldDisplayTest.php b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
index c4cf485..af34ab6 100644
--- a/core/modules/image/src/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
@@ -32,6 +32,8 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
    * Test image formatters on node display for public files.
    */
   function testImageFieldFormattersPublic() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->_testImageFieldFormatters('public');
   }
 
@@ -39,6 +41,8 @@ function testImageFieldFormattersPublic() {
    * Test image formatters on node display for private files.
    */
   function testImageFieldFormattersPrivate() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Remove access content permission from anonymous users.
     user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access content' => FALSE));
     $this->_testImageFieldFormatters('private');
@@ -323,6 +327,8 @@ function testImageFieldSettings() {
    * Test use of a default image with an image field.
    */
   function testImageFieldDefaultImage() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     /** @var \Drupal\Core\Render\RendererInterface $renderer */
     $renderer = $this->container->get('renderer');
 
diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php
index b3397cc..d1e21a0 100644
--- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuNodeTest.php
@@ -34,6 +34,8 @@ class MenuNodeTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalPlaceBlock('system_menu_block:main');
     $this->drupalPlaceBlock('page_title_block');
 
diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php
index f8c26c9..7d97fb8 100644
--- a/core/modules/menu_ui/src/Tests/MenuTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuTest.php
@@ -543,6 +543,8 @@ function testSystemMenuRename() {
    * Tests that menu items pointing to unpublished nodes are editable.
    */
   function testUnpublishedNodeMenuItem() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalLogin($this->drupalCreateUser(array('access administration pages', 'administer blocks', 'administer menu', 'create article content', 'bypass node access')));
     // Create an unpublished node.
     $node = $this->drupalCreateNode(array(
diff --git a/core/modules/node/src/Tests/NodeBlockFunctionalTest.php b/core/modules/node/src/Tests/NodeBlockFunctionalTest.php
index 386188f..06141fe 100644
--- a/core/modules/node/src/Tests/NodeBlockFunctionalTest.php
+++ b/core/modules/node/src/Tests/NodeBlockFunctionalTest.php
@@ -45,6 +45,8 @@ class NodeBlockFunctionalTest extends NodeTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create users and test node.
     $this->adminUser = $this->drupalCreateUser(array('administer content types', 'administer nodes', 'administer blocks', 'access content overview'));
     $this->webUser = $this->drupalCreateUser(array('access content', 'create article content'));
diff --git a/core/modules/node/src/Tests/NodeTypeTest.php b/core/modules/node/src/Tests/NodeTypeTest.php
index a8fa54d..2c8094c 100644
--- a/core/modules/node/src/Tests/NodeTypeTest.php
+++ b/core/modules/node/src/Tests/NodeTypeTest.php
@@ -48,6 +48,7 @@ function testNodeTypeGetFunctions() {
    * Tests creating a content type programmatically and via a form.
    */
   function testNodeTypeCreation() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
     // Create a content type programmatically.
     $type = $this->drupalCreateContentType();
 
@@ -89,6 +90,8 @@ function testNodeTypeCreation() {
    * Tests editing a node type using the UI.
    */
   function testNodeTypeEditing() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types', 'administer node fields'));
     $this->drupalLogin($web_user);
 
diff --git a/core/modules/node/src/Tests/Views/FrontPageTest.php b/core/modules/node/src/Tests/Views/FrontPageTest.php
index 5cd78a8..229be5d 100644
--- a/core/modules/node/src/Tests/Views/FrontPageTest.php
+++ b/core/modules/node/src/Tests/Views/FrontPageTest.php
@@ -47,6 +47,8 @@ class FrontPageTest extends ViewTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->nodeStorage = $this->container->get('entity.manager')
       ->getStorage('node');
   }
diff --git a/core/modules/page_cache/src/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php
index 23ddb84..85a7275 100644
--- a/core/modules/page_cache/src/StackMiddleware/PageCache.php
+++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php
@@ -8,6 +8,7 @@
 namespace Drupal\page_cache\StackMiddleware;
 
 use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheableResponseInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\PageCache\RequestPolicyInterface;
 use Drupal\Core\PageCache\ResponsePolicyInterface;
@@ -224,7 +225,7 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch
     $date = $response->getExpires()->getTimestamp();
     $expire = ($date > time()) ? $date : Cache::PERMANENT;
 
-    $tags = explode(' ', $response->headers->get('X-Drupal-Cache-Tags'));
+    $tags = ($response instanceof CacheableResponseInterface) ? $response->getCacheableMetadata()->getCacheTags() : [];
     $this->set($request, $response, $expire, $tags);
 
     // Mark response as a cache miss.
diff --git a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
index 22ae7b2..a8a7f0b 100644
--- a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
@@ -33,6 +33,8 @@ class PageCacheTagsIntegrationTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->enablePageCaching();
   }
 
diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php
index a2278e7..718584e 100644
--- a/core/modules/page_cache/src/Tests/PageCacheTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTest.php
@@ -257,6 +257,8 @@ function testPageCache() {
    * roles.
    */
   public function testPageCacheAnonymousRolePermissions() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $config = $this->config('system.performance');
     $config->set('cache.page.max_age', 300);
     $config->save();
@@ -309,6 +311,8 @@ public function testPageCacheAnonymousRolePermissions() {
    * Tests the 4xx-response cache tag is added and invalidated.
    */
   function testPageCacheAnonymous403404() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $admin_url = Url::fromRoute('system.admin');
     $invalid_url = 'foo/does_not_exist';
     $tests = [
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
index b42831b..7e33bfb 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
@@ -72,6 +72,7 @@ protected function setUp() {
    * Tests responsive image formatters on node display for public files.
    */
   public function testResponsiveImageFieldFormattersPublic() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
     $this->addTestImageStyleMappings();
     $this->doTestResponsiveImageFieldFormatters('public');
   }
@@ -80,6 +81,7 @@ public function testResponsiveImageFieldFormattersPublic() {
    * Tests responsive image formatters on node display for private files.
    */
   public function testResponsiveImageFieldFormattersPrivate() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
     $this->addTestImageStyleMappings();
     // Remove access content permission from anonymous users.
     user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access content' => FALSE));
@@ -90,6 +92,7 @@ public function testResponsiveImageFieldFormattersPrivate() {
    * Test responsive image formatters when image style is empty.
    */
   public function testResponsiveImageFieldFormattersEmptyStyle() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
     $this->addTestImageStyleMappings(TRUE);
     $this->doTestResponsiveImageFieldFormatters('public', TRUE);
   }
diff --git a/core/modules/rest/src/Tests/PageCacheTest.php b/core/modules/rest/src/Tests/PageCacheTest.php
index 3ae0084..cbc6b2c 100644
--- a/core/modules/rest/src/Tests/PageCacheTest.php
+++ b/core/modules/rest/src/Tests/PageCacheTest.php
@@ -25,6 +25,8 @@ class PageCacheTest extends RESTTestBase {
    * Tests that configuration changes also clear the page cache.
    */
   public function testConfigChangePageCache() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->enableService('entity:entity_test', 'GET');
     // Allow anonymous users to issue GET requests.
     $permissions = $this->entityPermissions('entity_test', 'view');
diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
index 5f378ee..389fbe0 100644
--- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
+++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
@@ -76,6 +76,8 @@ protected function setUp() {
    * Checks the behavior of the Serializer callback paths and row plugins.
    */
   public function testSerializerResponses() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Test the serialize callback.
     $view = Views::getView('test_serializer_display_field');
     $view->initDisplay();
@@ -204,6 +206,8 @@ protected function addRequestWithFormat($format) {
    * Tests REST export with views render caching enabled.
    */
   public function testRestRenderCaching() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalLogin($this->adminUser);
     /** @var \Drupal\Core\Render\RenderCacheInterface $render_cache */
     $render_cache = \Drupal::service('render_cache');
diff --git a/core/modules/search/src/Tests/SearchPageCacheTagsTest.php b/core/modules/search/src/Tests/SearchPageCacheTagsTest.php
index 6a74718..5727b9c 100644
--- a/core/modules/search/src/Tests/SearchPageCacheTagsTest.php
+++ b/core/modules/search/src/Tests/SearchPageCacheTagsTest.php
@@ -41,6 +41,8 @@ class SearchPageCacheTagsTest extends SearchTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create user.
     $this->searchingUser = $this->drupalCreateUser(array('search content', 'access user profiles'));
 
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 5b62c50..d457b2f 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -3019,4 +3019,18 @@ protected function assertNoCacheTag($cache_tag) {
     $this->assertFalse(in_array($cache_tag, $cache_tags), "'" . $cache_tag . "' is absent in the X-Drupal-Cache-Tags header.");
   }
 
+  /**
+   * Enables/disables the cacheability headers.
+   *
+   * Sets the http.response.debug_cacheability_headers container parameter.
+   *
+   * @param bool $value
+   *   (optional) Whether the debugging cacheability headers should be sent.
+   */
+  protected function setHttpResponseDebugCacheabilityHeaders($value = TRUE) {
+    $this->setContainerParameter('http.response.debug_cacheability_headers', $value);
+    $this->rebuildContainer();
+    $this->resetAll();
+  }
+
 }
diff --git a/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php b/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php
index b3b363a..95c4799 100644
--- a/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php
+++ b/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php
@@ -32,6 +32,8 @@ class EarlyRenderingControllerTest extends WebTestBase {
    * Tests theme preprocess functions being able to attach assets.
    */
   function testEarlyRendering() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Render array: non-early & early.
     $this->drupalGet(Url::fromRoute('early_rendering_controller_test.render_array'));
     $this->assertResponse(200);
diff --git a/core/modules/system/src/Tests/Common/RenderWebTest.php b/core/modules/system/src/Tests/Common/RenderWebTest.php
index 4f11071..87458bd 100644
--- a/core/modules/system/src/Tests/Common/RenderWebTest.php
+++ b/core/modules/system/src/Tests/Common/RenderWebTest.php
@@ -30,6 +30,8 @@ class RenderWebTest extends WebTestBase {
    * Asserts the cache context for the wrapper format is always present.
    */
   function testWrapperFormatCacheContext() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalGet('common-test/type-link-active-class');
     $this->assertIdentical(0, strpos($this->getRawContent(), "<!DOCTYPE html>\n<html"));
     $this->assertIdentical('text/html; charset=UTF-8', $this->drupalGetHeader('Content-Type'));
diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
index dd35bbd..7533640 100644
--- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
+++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
@@ -58,6 +58,8 @@
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Give anonymous users permission to view test entities, so that we can
     // verify the cache tags of cached versions of test entity pages.
     $user_role = Role::load(RoleInterface::ANONYMOUS_ID);
diff --git a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php b/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php
index f38c62d..577d0d8 100644
--- a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php
@@ -74,6 +74,8 @@ public function testCacheContexts() {
    * Tests if the list cache tags are set.
    */
   public function testCacheTags() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalGet('entity_test/list');
     $this->assertCacheTag('entity_test_list');
   }
diff --git a/core/modules/system/src/Tests/Menu/LocalTasksTest.php b/core/modules/system/src/Tests/Menu/LocalTasksTest.php
index 015f4de..251d6ef 100644
--- a/core/modules/system/src/Tests/Menu/LocalTasksTest.php
+++ b/core/modules/system/src/Tests/Menu/LocalTasksTest.php
@@ -104,6 +104,8 @@ protected function assertNoLocalTasks($level = 0) {
    * Tests the plugin based local tasks.
    */
   public function testPluginLocalTask() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Verify local tasks defined in the hook.
     $this->drupalGet(Url::fromRoute('menu_test.tasks_default'));
     $this->assertLocalTasks([
diff --git a/core/modules/system/src/Tests/Pager/PagerTest.php b/core/modules/system/src/Tests/Pager/PagerTest.php
index 4d7e0a1..f2c98a1 100644
--- a/core/modules/system/src/Tests/Pager/PagerTest.php
+++ b/core/modules/system/src/Tests/Pager/PagerTest.php
@@ -73,6 +73,8 @@ function testActiveClass() {
    * Test proper functioning of the query parameters and the pager cache context.
    */
   protected function testPagerQueryParametersAndCacheContext() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // First page.
     $this->drupalGet('pager-test/query-parameters');
     $this->assertText(t('Pager calls: 0'), 'Initial call to pager shows 0 calls.');
diff --git a/core/modules/system/src/Tests/Render/DisplayVariantTest.php b/core/modules/system/src/Tests/Render/DisplayVariantTest.php
index c4c37bb..1f933eb 100644
--- a/core/modules/system/src/Tests/Render/DisplayVariantTest.php
+++ b/core/modules/system/src/Tests/Render/DisplayVariantTest.php
@@ -27,6 +27,8 @@ class DisplayVariantTest extends WebTestBase {
    * Tests selecting the variant and passing configuration.
    */
   function testPageDisplayVariantSelectionEvent() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Tests that our display variant was selected, and that its configuration
     // was passed correctly. If the configuration wasn't passed, we'd get an
     // error page here.
diff --git a/core/modules/system/src/Tests/Render/UrlBubbleableMetadataBubblingTest.php b/core/modules/system/src/Tests/Render/UrlBubbleableMetadataBubblingTest.php
index 2ae068e..9ab0b69 100644
--- a/core/modules/system/src/Tests/Render/UrlBubbleableMetadataBubblingTest.php
+++ b/core/modules/system/src/Tests/Render/UrlBubbleableMetadataBubblingTest.php
@@ -30,6 +30,8 @@ class UrlBubbleableMetadataBubblingTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
     $this->dumpHeaders = TRUE;
+
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Routing/RouterTest.php b/core/modules/system/src/Tests/Routing/RouterTest.php
index 17345fa..fbb27d0 100644
--- a/core/modules/system/src/Tests/Routing/RouterTest.php
+++ b/core/modules/system/src/Tests/Routing/RouterTest.php
@@ -32,6 +32,8 @@ class RouterTest extends WebTestBase {
    * Confirms that our FinishResponseSubscriber logic works properly.
    */
   public function testFinishResponseSubscriber() {
+    $this->setHttpResponseDebugCacheabilityHeaders();
+
     $renderer_required_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
     $expected_cache_contexts = Cache::mergeContexts($renderer_required_cache_contexts, ['url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT]);
 
diff --git a/core/modules/system/src/Tests/System/TokenReplaceWebTest.php b/core/modules/system/src/Tests/System/TokenReplaceWebTest.php
index ba94e51..d230be4 100644
--- a/core/modules/system/src/Tests/System/TokenReplaceWebTest.php
+++ b/core/modules/system/src/Tests/System/TokenReplaceWebTest.php
@@ -29,6 +29,8 @@ class TokenReplaceWebTest extends WebTestBase {
    * Tests a token replacement on an actual website.
    */
   public function testTokens() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $node = $this->drupalCreateNode();
     $account = $this->drupalCreateUser();
     $this->drupalLogin($account);
diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
index 283b41d..5d4ea2e 100644
--- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php
+++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
@@ -46,6 +46,8 @@ function testTwigVariableDataTypes() {
    * Tests the url and url_generate Twig functions.
    */
   public function testTwigUrlGenerator() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalGet('twig-theme-test/url-generator');
     // Find the absolute URL of the current site.
     $url_generator = $this->container->get('url_generator');
@@ -75,6 +77,8 @@ public function testTwigUrlGenerator() {
    * Tests the link_generator Twig functions.
    */
   public function testTwigLinkGenerator() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalGet('twig-theme-test/link-generator');
 
      /** @var \Drupal\Core\Utility\LinkGenerator $link_generator */
diff --git a/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php b/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php
index 759f646..672ae4e 100644
--- a/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php
+++ b/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php
@@ -60,6 +60,8 @@ class ToolbarCacheContextsTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->adminUser = $this->drupalCreateUser($this->perms);
     $this->adminUser2 = $this->drupalCreateUser($this->perms);
   }
diff --git a/core/modules/tracker/src/Tests/TrackerTest.php b/core/modules/tracker/src/Tests/TrackerTest.php
index 425c4a1..f7e451c 100644
--- a/core/modules/tracker/src/Tests/TrackerTest.php
+++ b/core/modules/tracker/src/Tests/TrackerTest.php
@@ -69,6 +69,8 @@ protected function setUp() {
    * Tests for the presence of nodes on the global tracker listing.
    */
   function testTrackerAll() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalLogin($this->user);
 
     $unpublished = $this->drupalCreateNode(array(
@@ -135,6 +137,8 @@ function testTrackerAll() {
    * Tests for the presence of nodes on a user's tracker listing.
    */
   function testTrackerUser() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalLogin($this->user);
 
     $unpublished = $this->drupalCreateNode(array(
diff --git a/core/modules/user/src/Tests/UserLoginTest.php b/core/modules/user/src/Tests/UserLoginTest.php
index 39ffed5..106d6da 100644
--- a/core/modules/user/src/Tests/UserLoginTest.php
+++ b/core/modules/user/src/Tests/UserLoginTest.php
@@ -21,6 +21,8 @@ class UserLoginTest extends WebTestBase {
    * Tests login with destination.
    */
   function testLoginCacheTagsAndDestination() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalGet('user/login');
     // The user login form says "Enter your <site name> username.", hence it
     // depends on config:system.site, and its cache tags should be present.
diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/src/Tests/UserRegistrationTest.php
index 1e16bc7..b504fab 100644
--- a/core/modules/user/src/Tests/UserRegistrationTest.php
+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -224,6 +224,8 @@ public function testUuidFormState() {
   }
 
   function testRegistrationDefaultValues() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Don't require email verification and allow registration by site visitors
     // without administrator approval.
     $config_user_settings = $this->config('user.settings')
@@ -287,6 +289,8 @@ public function testUniqueFields() {
    * Tests Field API fields on user registration forms.
    */
   function testRegistrationWithUserFields() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create a field on 'user' entity type.
     $field_storage = entity_create('field_storage_config', array(
       'field_name' => 'test_user_field',
diff --git a/core/modules/user/src/Tests/Views/AccessRoleTest.php b/core/modules/user/src/Tests/Views/AccessRoleTest.php
index a6230b3..aa55253 100644
--- a/core/modules/user/src/Tests/Views/AccessRoleTest.php
+++ b/core/modules/user/src/Tests/Views/AccessRoleTest.php
@@ -31,6 +31,8 @@ class AccessRoleTest extends AccessTestBase {
    * Tests role access plugin.
    */
   function testAccessRole() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     /** @var \Drupal\views\ViewEntityInterface $view */
     $view = \Drupal::entityManager()->getStorage('view')->load('test_access_role');
     $display = &$view->getDisplay('default');
diff --git a/core/modules/views/src/Tests/GlossaryTest.php b/core/modules/views/src/Tests/GlossaryTest.php
index d79b183..4a51be8 100644
--- a/core/modules/views/src/Tests/GlossaryTest.php
+++ b/core/modules/views/src/Tests/GlossaryTest.php
@@ -32,6 +32,8 @@ class GlossaryTest extends ViewTestBase {
    * Tests the default glossary view.
    */
   public function testGlossaryView() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create a content type and add some nodes, with a non-random title.
     $type = $this->drupalCreateContentType();
     $nodes_per_char = array(
diff --git a/core/modules/views/src/Tests/Handler/FieldWebTest.php b/core/modules/views/src/Tests/Handler/FieldWebTest.php
index ddc9b50..9c93274 100644
--- a/core/modules/views/src/Tests/Handler/FieldWebTest.php
+++ b/core/modules/views/src/Tests/Handler/FieldWebTest.php
@@ -65,6 +65,8 @@ protected function viewsData() {
    * Tests the click sorting functionality.
    */
   public function testClickSorting() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalGet('test_click_sort');
     $this->assertResponse(200);
 
diff --git a/core/modules/views/src/Tests/Plugin/CacheWebTest.php b/core/modules/views/src/Tests/Plugin/CacheWebTest.php
index 85194e2..0220b87 100644
--- a/core/modules/views/src/Tests/Plugin/CacheWebTest.php
+++ b/core/modules/views/src/Tests/Plugin/CacheWebTest.php
@@ -48,6 +48,8 @@ protected function setUp() {
    * Tests the output caching on an actual page.
    */
   public function testCacheOutputOnPage() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $view = Views::getView('test_display');
     $view->storage->setStatus(TRUE);
     $view->setDisplay('page_1');
diff --git a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php b/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
index 1ce4f59..af24379 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
+++ b/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
@@ -47,6 +47,8 @@ protected function setUp() {
    * Tests arguments.
    */
   public function testArguments() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->drupalGet('test_route_without_arguments');
     $this->assertResponse(200);
     $result = $this->xpath('//span[@class="field-content"]');
diff --git a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
index 8906cfd..8f546a5 100644
--- a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
+++ b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
@@ -222,6 +222,8 @@ public function testTextInputRequired() {
    * Tests exposed forms with exposed sort and items per page.
    */
   public function testExposedSortAndItemsPerPage() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     for ($i = 0; $i < 50; $i++) {
       $entity = EntityTest::create([
       ]);
diff --git a/core/modules/views/src/Tests/Plugin/PagerTest.php b/core/modules/views/src/Tests/Plugin/PagerTest.php
index bdd95ed..02aaaa3 100644
--- a/core/modules/views/src/Tests/Plugin/PagerTest.php
+++ b/core/modules/views/src/Tests/Plugin/PagerTest.php
@@ -209,6 +209,8 @@ public function testLimit() {
    * Tests the normal pager.
    */
   public function testNormalPager() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     // Create 11 nodes and make sure that everyone is returned.
     // We create 11 nodes, because the default pager plugin had 10 items per page.
     $this->drupalCreateContentType(array('type' => 'page'));
diff --git a/core/modules/views_ui/src/Tests/DisplayPathTest.php b/core/modules/views_ui/src/Tests/DisplayPathTest.php
index 5e8f595..0b7d2a1 100644
--- a/core/modules/views_ui/src/Tests/DisplayPathTest.php
+++ b/core/modules/views_ui/src/Tests/DisplayPathTest.php
@@ -121,6 +121,8 @@ public function testDeleteWithNoPath() {
    * Tests the menu and tab option form.
    */
   public function testMenuOptions() {
+    $this->setHttpResponseDebugCacheabilityHeaders(TRUE);
+
     $this->container->get('module_installer')->install(array('menu_ui'));
     $this->drupalGet('admin/structure/views/view/test_view');
 
diff --git a/sites/default/default.services.yml b/sites/default/default.services.yml
index 4ab0662..e806496 100644
--- a/sites/default/default.services.yml
+++ b/sites/default/default.services.yml
@@ -115,6 +115,17 @@ parameters:
       #
       # @default []
       tags: []
+  # Cacheability debugging:
+  #
+  # Responses with cacheability metadata (CacheableResponseInterface instances)
+  # get X-Drupal-Cache-Tags and X-Drupal-Cache-Contexts headers.
+  #
+  # For more information about debugging cacheable responses, se
+  # https://www.drupal.org/developing/api/8/response/cacheable-response-interface
+  #
+  # Not recommended in production environments
+  # @default false
+  http.response.debug_cacheability_headers: false
   factory.keyvalue:
     {}
     # Default key/value storage service to use.
