diff --git a/core/modules/page_cache/src/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php
index 1629c14..7fe4815 100644
--- a/core/modules/page_cache/src/StackMiddleware/PageCache.php
+++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php
@@ -222,11 +222,19 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch
       return $response;
     }
 
-    // Use the actual timestamp from an Expires header, if available.
-    $date = $response->getExpires()->getTimestamp();
-    $expire = ($date > time()) ? $date : Cache::PERMANENT;
-
-    $tags = explode(' ', $response->headers->get('X-Drupal-Cache-Tags'));
+    // If there is cachability metadata on the response, invalidation is
+    // performed via cache tags and as a result the response can be cached
+    // indefinitely. Otherwise the expiry time of the cache object is determined
+    // by response headers (Cache-Control s-max-age, max-age or Expire in that
+    // order).
+    if ($response->headers->has('X-Drupal-Cache-Tags')) {
+      $tags = explode(' ', $response->headers->get('X-Drupal-Cache-Tags'));
+      $expire = Cache::PERMANENT;
+    }
+    else {
+      $tags = [];
+      $expire = $response->getDate()->getTimestamp() + $response->getMaxAge();
+    }
     $this->set($request, $response, $expire, $tags);
 
     // Mark response as a cache miss.
