diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
index f6eefe0069..d6328a19d9 100644
--- src/wp-includes/taxonomy.php
+++ src/wp-includes/taxonomy.php
@@ -3877,17 +3877,27 @@ function _update_post_term_count( $terms, $taxonomy ) {
 		$object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
 	}
 
+	$post_statuses = array( 'publish' );
+
+	/**
+	 * Filters the post statuses for updating the term count.
+	 *
+	 * @param array $post_statuses List of post statuses to include in the count. Default is 'publish'.
+	 * @param int   $taxonomy      Current taxonomy object.
+	 */
+	$post_statuses = esc_sql( apply_filters( 'update_post_term_count_statuses', $post_statuses, $taxonomy ) );
+
 	foreach ( (array) $terms as $term ) {
 		$count = 0;
 
 		// Attachments can be 'inherit' status, we need to base count off the parent's status if so.
 		if ( $check_attachments ) {
-			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status = 'publish' OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) = 'publish' ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
+			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status IN ('" . implode("', '", $post_statuses ) . "') OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) IN ('" . implode("', '", $post_statuses ) . "') ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
 		}
 
 		if ( $object_types ) {
 			// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration
-			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('" . implode( "', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
+			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status IN ('" . implode("', '", $post_statuses ) . "') AND post_type IN ('" . implode( "', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
 		}
 
 		/** This action is documented in wp-includes/taxonomy.php */
diff --git tests/phpunit/tests/term/termCounts.php tests/phpunit/tests/term/termCounts.php
index c6fa42e4fc..3d8ed55e14 100644
--- tests/phpunit/tests/term/termCounts.php
+++ tests/phpunit/tests/term/termCounts.php
@@ -224,12 +224,75 @@ class Tests_Term_termCount extends WP_UnitTestCase {
 		);
 	}
 
+	function add_custom_status_to_counted_statuses( $statuses ) {
+		array_push( $statuses, 'custom' );
+		return $statuses;
+	}
+
+	/**
+	 * Term counts incremented correctly when the `update_post_term_count_statuses` filter is used.
+	 *
+	 * @covers ::wp_update_term_count
+	 * @dataProvider data_term_count_changes_for_update_post_term_count_statuses_filter
+	 * @ticket 38843
+	 *
+	 * @param string $post_status New post status.
+	 * @param int    $change      Expected change.
+	 */
+	public function test_term_count_changes_for_update_post_term_count_statuses_filter( $post_status, $change ) {
+		$term_count = get_term( self::$attachment_term )->count;
+
+		add_filter( 'update_post_term_count_statuses', array( $this, 'add_custom_status_to_counted_statuses' ) );
+
+		$post_id = $this->factory()->post->create( array( 'post_status' => $post_status ) );
+		wp_add_object_terms( $post_id, self::$attachment_term, 'wp_test_tax_counts' );
+		$attachment_id = self::factory()->attachment->create_object(
+			array(
+				'file'        => 'image.jpg',
+				'post_parent' => $post_id,
+				'post_status' => 'inherit',
+			)
+		);
+		wp_add_object_terms( $attachment_id, self::$attachment_term, 'wp_test_tax_counts' );
+
+		$expected = $term_count + $change;
+		$this->assertSame( $expected, get_term( self::$attachment_term )->count );
+
+		remove_filter( 'update_post_term_count_statuses', array( $this, 'add_custom_status_to_counted_statuses' ) );
+
+	}
+
+	/**
+	 * Data provider for test_term_count_changes_for_update_post_term_count_statuses_filter.
+	 *
+	 * @return array[] {
+	 *     @type string $post_status New post status.
+	 *     @type int    $change      Expected change.
+	 * }
+	 */
+	function data_term_count_changes_for_update_post_term_count_statuses_filter() {
+		return array(
+			// 0. Published post
+			array( 'publish', 2 ),
+			// 1. Auto draft
+			array( 'auto-draft', 0 ),
+			// 2. Draft
+			array( 'draft', 0 ),
+			// 3. Private post
+			array( 'private', 0 ),
+			// 4. Custom post status
+			array( 'custom', 1 ),
+		);
+	}
+
+
+
 	/**
 	 * Term counts incremented correctly for posts with attachment.
 	 *
 	 * @covers ::wp_update_term_count
 	 * @dataProvider data_term_count_changes_for_post_statuses_with_attachments
-	 *
+
 	 * @param string $post_status New post status.
 	 * @param int    $change      Expected change.
 	 */
