diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php
index 91edacf76f..a7af977c1d 100644
--- a/src/wp-includes/post.php
+++ b/src/wp-includes/post.php
@@ -2130,6 +2130,7 @@ function is_post_type_viewable( $post_type ) {
  * For all others, the 'publicly_queryable' value will be used.
  *
  * @since 5.7.0
+ * @since 5.9.0 Added `is_post_status_viewable` hook to filter the result.
  *
  * @param string|stdClass $post_status Post status name or object.
  * @return bool Whether the post status should be considered viewable.
@@ -2150,7 +2151,23 @@ function is_post_status_viewable( $post_status ) {
 		return false;
 	}
 
-	return $post_status->publicly_queryable || ( $post_status->_builtin && $post_status->public );
+	$is_viewable = $post_status->publicly_queryable || ( $post_status->_builtin && $post_status->public );
+
+	/**
+	 * Filters whether a post status is considered "viewable".
+	 *
+	 * To avoid the potential for type errors in PHP 8.1 or later, this filter
+	 * must return a boolean true for the post status to be considered viewable.
+	 *
+	 * All other values (even truthy values) will result in the function
+	 * is_post_status_viewable() returning false.
+	 *
+	 * @since 5.9.0
+	 *
+	 * @param bool     $is_viewable Whether the post status is "viewable".
+	 * @param stdClass $post_status Post status object.
+	 */
+	return true === apply_filters( 'is_post_status_viewable', $is_viewable, $post_status );
 }
 
 /**
