diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index e51e4358bc..d55a8492d0 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -11,6 +11,7 @@
 use Drupal\Core\Render\Element;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Url;
+use Drupal\node\NodeInterface;
 use Drupal\taxonomy\Entity\Term;
 
 /**
@@ -304,20 +305,21 @@ function taxonomy_node_insert(EntityInterface $node) {
  * The index lists all terms that are related to a given node entity, and is
  * therefore maintained at the entity level.
  *
- * @param \Drupal\node\Entity\Node $node
+ * @param \Drupal\node\NodeInterface $node
  *   The node entity.
  */
-function taxonomy_build_node_index($node) {
+function taxonomy_build_node_index(NodeInterface $node) {
   // We maintain a denormalized table of term/node relationships, containing
   // only data for current, published nodes.
   if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !(\Drupal::entityTypeManager()->getStorage('node') instanceof SqlContentEntityStorage)) {
     return;
   }
 
-  $status = $node->isPublished();
-  $sticky = (int) $node->isSticky();
-  // We only maintain the taxonomy index for published nodes.
-  if ($status && $node->isDefaultRevision()) {
+  // We only maintain the taxonomy index for the default node revision.
+  if ($node->isDefaultRevision()) {
+    $status = (int) $node->isPublished();
+    $sticky = (int) $node->isSticky();
+
     // Collect a unique list of all the term IDs from all node fields.
     $tid_all = [];
     $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem';
@@ -340,7 +342,7 @@ function taxonomy_build_node_index($node) {
       $connection = \Drupal::database();
       foreach ($tid_all as $tid) {
         $connection->merge('taxonomy_index')
-          ->key(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()])
+          ->key(['nid' => $node->id(), 'tid' => $tid, 'status' => $status])
           ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()])
           ->execute();
       }
diff --git a/core/modules/taxonomy/taxonomy.post_update.php b/core/modules/taxonomy/taxonomy.post_update.php
index f261092d0e..ef5fcc3156 100644
--- a/core/modules/taxonomy/taxonomy.post_update.php
+++ b/core/modules/taxonomy/taxonomy.post_update.php
@@ -5,6 +5,9 @@
  * Post update functions for Taxonomy.
  */
 
+use Drupal\Core\Site\Settings;
+use Drupal\node\NodeInterface;
+
 /**
  * Implements hook_removed_post_updates().
  */
@@ -25,3 +28,48 @@ function taxonomy_removed_post_updates() {
 function taxonomy_post_update_clear_views_argument_validator_plugins_cache(): void {
   // An empty update will flush all caches.
 }
+
+/**
+ * Add unpublished nodes to the taxonomy index table.
+ */
+function taxonomy_post_update_add_unpublished_nodes_to_taxonomy_index(&$sandbox) {
+  $database = \Drupal::database();
+
+  if (!isset($sandbox['total'])) {
+    // Initialize state for future calls.
+    $sandbox['last'] = 0;
+    $sandbox['count'] = 0;
+
+    $query = $database->select('node_field_data', 'n')
+      ->condition('n.status', NodeInterface::NOT_PUBLISHED);
+    $sandbox['total'] = $query->countQuery()->execute()->fetchField();
+  }
+
+  if ($sandbox['total']) {
+    // Operate on every unpublished node, in batches.
+    $batch_size = Settings::get('entity_update_batch_size', 100);
+    $query = $database->select('node_field_data', 'n');
+    $query->fields('n', ['nid'])
+      ->condition('n.nid', $sandbox['last'], '>')
+      ->condition('n.status', NodeInterface::NOT_PUBLISHED)
+      ->orderBy('n.nid', 'ASC')
+      ->range(0, $batch_size);
+    $nids = $query->execute()->fetchCol();
+    $node_storage = \Drupal::entityTypeManager()->getStorage('node');
+    // Build the taxonomy index for each node.
+    foreach ($node_storage->loadMultiple($nids) as $node) {
+      // Delete node index to avoid integrity constraint violation errors.
+      taxonomy_delete_node_index($node);
+      taxonomy_build_node_index($node);
+      $sandbox['last'] = $node->id();
+    }
+    $sandbox['count'] += $batch_size;
+  }
+  // Finish after all the unpublished nodes have been processed.
+  if ($sandbox['count'] < $sandbox['total']) {
+    $sandbox['#finished'] = FALSE;
+  }
+  else {
+    $sandbox['#finished'] = TRUE;
+  }
+}
diff --git a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
index cf011b157e..13b6028542 100644
--- a/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
@@ -62,7 +62,7 @@ protected function setUp(): void {
     $handler_settings = [
       'target_bundles' => [
         $this->vocabulary->id() => $this->vocabulary->id(),
-       ],
+      ],
       'auto_create' => TRUE,
     ];
     $this->createEntityReferenceField('node', 'article', $this->fieldName1, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
@@ -126,6 +126,21 @@ public function testTaxonomyIndex() {
       ->fetchField();
     $this->assertEquals(1, $index_count, 'Term 1 is indexed once.');
 
+    // Check that the node status is stored correctly.
+    $node_status = (int) $connection->query('SELECT status FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
+      ':nid' => $node->id(),
+      ':tid' => $term_1->id(),
+    ])->fetchField();
+    $this->assertEquals(1, $node_status, 'Term 1 is index once with the node status published.');
+
+    // Un publish the article, this should update the register.
+    $node->setUnpublished()->save();
+    $node_status = (int) $connection->query('SELECT status FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
+      ':nid' => $node->id(),
+      ':tid' => $term_1->id(),
+    ])->fetchField();
+    $this->assertEquals(0, $node_status, 'Term 1 is index once with the node status unpublished.');
+
     // Update the article to change one term.
     $edit["{$this->fieldName1}[]"] = $term_2->id();
     $this->drupalGet('node/' . $node->id() . '/edit');
