diff --git a/core/modules/media/media.permissions.yml b/core/modules/media/media.permissions.yml
index 5c5692c..a575cf5 100644
--- a/core/modules/media/media.permissions.yml
+++ b/core/modules/media/media.permissions.yml
@@ -9,6 +9,9 @@ administer media types:
 view media:
   title: 'View media'
 
+view own unpublished media:
+  title: 'View own unpublished media'
+
 # @todo: Deprecate some permissions in https://www.drupal.org/project/drupal/issues/2925459
 update media:
   title: 'Update own media'
diff --git a/core/modules/media/src/MediaAccessControlHandler.php b/core/modules/media/src/MediaAccessControlHandler.php
index b631da8..8f5dbcb 100644
--- a/core/modules/media/src/MediaAccessControlHandler.php
+++ b/core/modules/media/src/MediaAccessControlHandler.php
@@ -24,13 +24,25 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter
     $is_owner = ($account->id() && $account->id() === $entity->getOwnerId());
     switch ($operation) {
       case 'view':
-        $access_result = AccessResult::allowedIf($account->hasPermission('view media') && $entity->isPublished())
-          ->cachePerPermissions()
-          ->addCacheableDependency($entity);
-        if (!$access_result->isAllowed()) {
-          $access_result->setReason("The 'view media' permission is required and the media item must be published.");
+        if ($is_owner && !$entity->isPublished()) {
+          $owner_access = AccessResult::allowedIf($account->hasPermission('view own unpublished media'))
+            ->cachePerPermissions()
+            ->cachePerUser()
+            ->addCacheableDependency($entity);
+          if (!$owner_access->isAllowed()) {
+            $owner_access->setReason("The 'view own unpublished media' permission is required to view unpublished media.");
+          }
+          return $owner_access;
+        }
+        else {
+          $access_result = AccessResult::allowedIf($account->hasPermission('view media') && $entity->isPublished())
+            ->cachePerPermissions()
+            ->addCacheableDependency($entity);
+          if (!$access_result->isAllowed()) {
+            $access_result->setReason("The 'view media' permission is required and the media item must be published.");
+          }
+          return $access_result;
         }
-        return $access_result;
 
       case 'update':
         if ($account->hasPermission('edit any ' . $type . ' media')) {
diff --git a/core/modules/media/tests/src/Functional/MediaAccessTest.php b/core/modules/media/tests/src/Functional/MediaAccessTest.php
index ef9f648..a46872c 100644
--- a/core/modules/media/tests/src/Functional/MediaAccessTest.php
+++ b/core/modules/media/tests/src/Functional/MediaAccessTest.php
@@ -72,6 +72,21 @@ public function testMediaAccess() {
     /** @var \Drupal\user\RoleInterface $role */
     $role = Role::load(RoleInterface::AUTHENTICATED_ID);
 
+    // Test 'view own unpublished media' permission.
+    user_role_revoke_permissions($role->id(), ['view own unpublished media']);
+    $user_media->setUnpublished()->save();
+    $this->drupalGet('media/' . $user_media->id());
+    $this->assertCacheContext('user');
+    $this->assertNoCacheContext('user.permissions');
+    $assert_session->statusCodeEquals(403);
+    $access_result = $user_media->access('view', NULL, TRUE);
+    $this->assertSame("The 'view own unpublished media' permission is required to view unpublished media.", $access_result->getReason());
+    $this->grantPermissions($role, ['view own unpublished media']);
+    $this->drupalGet('media/' . $user_media->id());
+    $this->assertCacheContext('user');
+    $this->assertNoCacheContext('user.permissions');
+    $assert_session->statusCodeEquals(200);
+
     // Test 'view media' permission.
     user_role_revoke_permissions($role->id(), ['view media']);
     $this->drupalGet('media/' . $media->id());
