diff --git a/core/modules/block/js/block.js b/core/modules/block/js/block.js
index 1a9566facbdd53dd53accb570b2c5effdc011bae..5224f0a281ef34df8b87acbddfbd89f189b4fa98 100644
--- a/core/modules/block/js/block.js
+++ b/core/modules/block/js/block.js
@@ -46,7 +46,7 @@
       }
 
       $(
-        '[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-entity-bundlenode"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"]',
+        '[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-entity-bundlenode"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"], [data-drupal-selector="edit-visibility-response-status"]',
       ).drupalSetSummary(checkboxesSummary);
 
       $(
diff --git a/core/modules/block/src/BlockForm.php b/core/modules/block/src/BlockForm.php
index 90cd6823ffb4881561f2d1e4fd7136f7245b19f9..4d27062930cfef4be38d871d9d0bb2d1b848342f 100644
--- a/core/modules/block/src/BlockForm.php
+++ b/core/modules/block/src/BlockForm.php
@@ -247,16 +247,23 @@ protected function buildVisibilityInterface(array $form, FormStateInterface $for
       $form[$condition_id] = $condition_form;
     }
 
-    if (isset($form['entity_bundle:node'])) {
-      $form['entity_bundle:node']['negate']['#type'] = 'value';
-      $form['entity_bundle:node']['negate']['#title_display'] = 'invisible';
-      $form['entity_bundle:node']['negate']['#value'] = $form['entity_bundle:node']['negate']['#default_value'];
+    // Disable negation for specific conditions.
+    $disable_negation = [
+      'entity_bundle:node',
+      'language',
+      'response_status',
+      'user_role',
+    ];
+    foreach ($disable_negation as $condition) {
+      if (isset($form[$condition])) {
+        $form[$condition]['negate']['#type'] = 'value';
+        $form[$condition]['negate']['#value'] = $form[$condition]['negate']['#default_value'];
+      }
     }
+
     if (isset($form['user_role'])) {
       $form['user_role']['#title'] = $this->t('Roles');
       unset($form['user_role']['roles']['#description']);
-      $form['user_role']['negate']['#type'] = 'value';
-      $form['user_role']['negate']['#value'] = $form['user_role']['negate']['#default_value'];
     }
     if (isset($form['request_path'])) {
       $form['request_path']['#title'] = $this->t('Pages');
@@ -268,10 +275,6 @@ protected function buildVisibilityInterface(array $form, FormStateInterface $for
         $this->t('Hide for the listed pages'),
       ];
     }
-    if (isset($form['language'])) {
-      $form['language']['negate']['#type'] = 'value';
-      $form['language']['negate']['#value'] = $form['language']['negate']['#default_value'];
-    }
     return $form;
   }
 
diff --git a/core/modules/block/tests/src/Functional/BlockTest.php b/core/modules/block/tests/src/Functional/BlockTest.php
index 1b31a09e3863b79ee0346ad23bc96f6298aecbc4..4ea7a7534d3db20149a72ce128cc68017291cca4 100644
--- a/core/modules/block/tests/src/Functional/BlockTest.php
+++ b/core/modules/block/tests/src/Functional/BlockTest.php
@@ -35,11 +35,13 @@ public function testBlockVisibility() {
       'settings[label]' => $title,
       'settings[label_display]' => TRUE,
     ];
-    // Set the block to be hidden on any user path, and to be shown only to
-    // authenticated users.
+    // Set the block to be hidden on any user path, to be shown only to
+    // authenticated users, and to be shown only on 200 and 404 responses.
     $edit['visibility[request_path][pages]'] = '/user*';
     $edit['visibility[request_path][negate]'] = TRUE;
     $edit['visibility[user_role][roles][' . RoleInterface::AUTHENTICATED_ID . ']'] = TRUE;
+    $edit['visibility[response_status][status_codes][200]'] = 200;
+    $edit['visibility[response_status][status_codes][404]'] = 404;
     $this->drupalGet('admin/structure/block/add/' . $block_name . '/' . $default_theme);
     $this->assertSession()->checkboxChecked('edit-visibility-request-path-negate-0');
 
@@ -48,16 +50,26 @@ public function testBlockVisibility() {
 
     $this->clickLink('Configure');
     $this->assertSession()->checkboxChecked('edit-visibility-request-path-negate-1');
+    $this->assertSession()->checkboxChecked('edit-visibility-response-status-status-codes-200');
+    $this->assertSession()->checkboxChecked('edit-visibility-response-status-status-codes-404');
 
-    // Confirm that the block is displayed on the front page.
+    // Confirm that the block is displayed on the front page (200 response).
     $this->drupalGet('');
     $this->assertSession()->pageTextContains($title);
 
-    // Confirm that the block is not displayed according to block visibility
+    // Confirm that the block is not displayed according to path visibility
     // rules.
     $this->drupalGet('user');
     $this->assertSession()->pageTextNotContains($title);
 
+    // Confirm that the block is displayed on a 404 response.
+    $this->drupalGet('/0/null');
+    $this->assertSession()->pageTextContains($title);
+
+    // Confirm that the block is not displayed on a 403 response.
+    $this->drupalGet('/admin/config/system/cron');
+    $this->assertSession()->pageTextNotContains($title);
+
     // Confirm that the block is not displayed to anonymous users.
     $this->drupalLogout();
     $this->drupalGet('');
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index e6a5260d2b6e7327eb4e74129653542350407f81..1d8c72c76d973a0996e9510eedc226ea6de71167 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -357,6 +357,14 @@ condition.plugin.request_path:
     pages:
       type: string
 
+condition.plugin.response_status:
+  type: condition.plugin
+  mapping:
+    status_codes:
+      type: sequence
+      sequence:
+        type: integer
+
 system.feature_flags:
   type: config_object
   label: 'System Feature Flags'
diff --git a/core/modules/system/src/Plugin/Condition/ResponseStatus.php b/core/modules/system/src/Plugin/Condition/ResponseStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..aa82db66b99e1e50f25574ce72fb3df8ad973989
--- /dev/null
+++ b/core/modules/system/src/Plugin/Condition/ResponseStatus.php
@@ -0,0 +1,124 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\system\Plugin\Condition;
+
+use Drupal\Core\Condition\ConditionPluginBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+
+/**
+ * Provides a 'Response status' condition.
+ *
+ * @Condition(
+ *   id = "response_status",
+ *   label = @Translation("Response status"),
+ * )
+ */
+class ResponseStatus extends ConditionPluginBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The request stack.
+   */
+  protected RequestStack $requestStack;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
+    $instance = new static($configuration, $plugin_id, $plugin_definition);
+    $instance->setRequestStack($container->get('request_stack'));
+    return $instance;
+  }
+
+  public function setRequestStack(RequestStack $requestStack): void {
+    $this->requestStack = $requestStack;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isNegated(): bool {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration(): array {
+    return ['status_codes' => []] + parent::defaultConfiguration();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
+    $status_codes = [
+      Response::HTTP_OK => $this->t('Success (@status_code)', ['@status_code' => Response::HTTP_OK]),
+      Response::HTTP_FORBIDDEN => $this->t('Access denied (@status_code)', ['@status_code' => Response::HTTP_FORBIDDEN]),
+      Response::HTTP_NOT_FOUND => $this->t('Page not found (@status_code)', ['@status_code' => Response::HTTP_NOT_FOUND]),
+    ];
+    $form['status_codes'] = [
+      '#type' => 'checkboxes',
+      '#title' => $this->t('Response status'),
+      '#options' => $status_codes,
+      '#default_value' => $this->configuration['status_codes'],
+      '#description' => $this->t('Shows the block on pages with any matching response status. If nothing is checked, the block is shown on all pages. Other response statuses are not used.'),
+    ];
+    return parent::buildConfigurationForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
+    $this->configuration['status_codes'] = array_keys(array_filter($form_state->getValue('status_codes')));
+    parent::submitConfigurationForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function summary(): PluralTranslatableMarkup {
+    $allowed_codes = $this->configuration['status_codes'];
+    $status_codes = [Response::HTTP_OK, Response::HTTP_FORBIDDEN, Response::HTTP_NOT_FOUND];
+    $result = empty($allowed_codes) ? $status_codes : $allowed_codes;
+    $count = count($result);
+    $codes = implode(', ', $result);
+    if (!empty($this->configuration['negate'])) {
+      return $this->formatPlural($count, 'Request response code is not: @codes', 'Request response code is not one of the following: @codes', ['@codes' => $codes]);
+    }
+    return $this->formatPlural($count, 'Request response code is: @codes', 'Request response code is one of the following: @codes', ['@codes' => $codes]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function evaluate(): bool {
+    $allowed_codes = $this->configuration['status_codes'];
+    if (empty($allowed_codes)) {
+      return TRUE;
+    }
+    $exception = $this->requestStack->getCurrentRequest()->attributes->get('exception');
+    if ($exception) {
+      return ($exception instanceof HttpExceptionInterface && in_array($exception->getStatusCode(), $allowed_codes, TRUE));
+    }
+    return in_array(Response::HTTP_OK, $allowed_codes, TRUE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts(): array {
+    $contexts = parent::getCacheContexts();
+    $contexts[] = 'url.path';
+    return $contexts;
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Condition/ResponseStatusTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Condition/ResponseStatusTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f5690a6bf3ae6b5e007c1a8eac4852ca77128de
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Plugin/Condition/ResponseStatusTest.php
@@ -0,0 +1,287 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\KernelTests\Core\Plugin\Condition;
+
+use Drupal\Core\Condition\ConditionManager;
+use Drupal\KernelTests\KernelTestBase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+
+/**
+ * Tests the Response Status Condition, provided by the system module.
+ *
+ * @group Plugin
+ */
+class ResponseStatusTest extends KernelTestBase {
+
+  /**
+   * The condition plugin manager under test.
+   */
+  protected ConditionManager $pluginManager;
+
+  /**
+   * The request stack used for testing.
+   */
+  protected RequestStack $requestStack;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['system', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installConfig('system');
+
+    $this->pluginManager = $this->container->get('plugin.manager.condition');
+
+    // Set the test request stack in the container.
+    $this->requestStack = new RequestStack();
+    $this->container->set('request_stack', $this->requestStack);
+  }
+
+  /**
+   * Tests the request path condition.
+   *
+   * @dataProvider providerTestConditions
+   */
+  public function testConditions(array $status_codes, bool $negate, int $response_code, bool $expected_execute) {
+    if ($response_code === Response::HTTP_OK) {
+      $request = Request::create('/my/valid/page');
+    }
+    else {
+      $request = new Request();
+      $request->attributes->set('exception', new HttpException($response_code));
+    }
+    $this->requestStack->push($request);
+
+    /** @var \Drupal\system\Plugin\Condition\ResponseStatus $condition */
+    $condition = $this->pluginManager->createInstance('response_status');
+    $condition->setConfig('status_codes', $status_codes);
+    $condition->setConfig('negate', $negate);
+
+    $this->assertSame($expected_execute, $condition->execute());
+  }
+
+  /**
+   * Provides test data for testConditions.
+   */
+  public function providerTestConditions() {
+    // Default values with 200 response code.
+    yield [
+      'status_codes' => [],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_OK,
+      'expected_execute' => TRUE,
+    ];
+
+    // Default values with 403 response code.
+    yield [
+      'status_codes' => [],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_FORBIDDEN,
+      'expected_execute' => TRUE,
+    ];
+
+    // Default values with 404 response code.
+    yield [
+      'status_codes' => [],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_NOT_FOUND,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200 status code enabled with 200 response code.
+    yield [
+      'status_codes' => [Response::HTTP_OK => Response::HTTP_OK],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_OK,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200 status code enabled with 403 response code.
+    yield [
+      'status_codes' => [Response::HTTP_OK => Response::HTTP_OK],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_FORBIDDEN,
+      'expected_execute' => FALSE,
+    ];
+
+    // 200 status code enabled with 404 response code.
+    yield [
+      'status_codes' => [Response::HTTP_OK => Response::HTTP_OK],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_NOT_FOUND,
+      'expected_execute' => FALSE,
+    ];
+
+    // 403 status code enabled with 200 response code.
+    yield [
+      'status_codes' => [Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_OK,
+      'expected_execute' => FALSE,
+    ];
+
+    // 403 status code enabled with 403 response code.
+    yield [
+      'status_codes' => [Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_FORBIDDEN,
+      'expected_execute' => TRUE,
+    ];
+
+    // 403 status code enabled with 404 response code.
+    yield [
+      'status_codes' => [Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_NOT_FOUND,
+      'expected_execute' => FALSE,
+    ];
+
+    // 200,403 status code enabled with 200 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_OK,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200,403 status code enabled with 403 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_FORBIDDEN,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200,403 status code enabled with 404 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_NOT_FOUND,
+      'expected_execute' => FALSE,
+    ];
+
+    // 200,404 status code enabled with 200 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_OK,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200,404 status code enabled with 403 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_FORBIDDEN,
+      'expected_execute' => FALSE,
+    ];
+
+    // 200,404 status code enabled with 404 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_NOT_FOUND,
+      'expected_execute' => TRUE,
+    ];
+
+    // 403,404 status code enabled with 200 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_OK,
+      'expected_execute' => FALSE,
+    ];
+
+    // 403,404 status code enabled with 403 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_FORBIDDEN,
+      'expected_execute' => TRUE,
+    ];
+
+    // 403,404 status code enabled with 404 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_NOT_FOUND,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200,403,404 status code enabled with 200 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_OK,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200,403 status code enabled with 403 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_FORBIDDEN,
+      'expected_execute' => TRUE,
+    ];
+
+    // 200,403 status code enabled with 404 response code.
+    yield [
+      'status_codes' => [
+        Response::HTTP_OK => Response::HTTP_OK,
+        Response::HTTP_FORBIDDEN => Response::HTTP_FORBIDDEN,
+        Response::HTTP_NOT_FOUND => Response::HTTP_NOT_FOUND,
+      ],
+      'negate' => FALSE,
+      'response_code' => Response::HTTP_NOT_FOUND,
+      'expected_execute' => TRUE,
+    ];
+
+  }
+
+}