diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index 584feb7c53..ae3869a02c 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -85,19 +85,7 @@ public function get($key = '') {
     if (!isset($this->overriddenData)) {
       $this->setOverriddenData();
     }
-    if (empty($key)) {
-      return $this->overriddenData;
-    }
-    else {
-      $parts = explode('.', $key);
-      if (count($parts) == 1) {
-        return isset($this->overriddenData[$key]) ? $this->overriddenData[$key] : NULL;
-      }
-      else {
-        $value = NestedArray::getValue($this->overriddenData, $parts, $key_exists);
-        return $key_exists ? $value : NULL;
-      }
-    }
+    return self::extractKeyedData($this->overriddenData, $key);
   }
 
   /**
@@ -141,6 +129,27 @@ public function setModuleOverride(array $data) {
     return $this;
   }
 
+  /**
+   * Returns overrides that apply to this configuration.
+   *
+   * Simply comparing the the data from getOriginal() with and without overrides
+   * does not help to detect overrides if the override happens to have the same
+   * value as the original data.
+   *
+   * @param string $key
+   *   A string that maps to a key within the configuration data.
+   *
+   * @return mixed
+   *   The value of the override or NULL if not overwritten.
+   */
+  public function getOverrides($key = '') {
+    $overrides = $this->mergeOverridesWithData([]);
+    if (empty($overrides)) {
+      return NULL;
+    }
+    return self::extractKeyedData($overrides, $key);
+  }
+
   /**
    * Sets the current data for this configuration object.
    *
@@ -153,13 +162,7 @@ public function setModuleOverride(array $data) {
    *   The configuration object.
    */
   protected function setOverriddenData() {
-    $this->overriddenData = $this->data;
-    if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
-      $this->overriddenData = NestedArray::mergeDeepArray([$this->overriddenData, $this->moduleOverrides], TRUE);
-    }
-    if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
-      $this->overriddenData = NestedArray::mergeDeepArray([$this->overriddenData, $this->settingsOverrides], TRUE);
-    }
+    $this->overriddenData = $this->mergeOverridesWithData($this->data);
     return $this;
   }
 
@@ -280,27 +283,29 @@ public function getOriginal($key = '', $apply_overrides = TRUE) {
     $original_data = $this->originalData;
     if ($apply_overrides) {
       // Apply overrides.
-      if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
-        $original_data = NestedArray::mergeDeepArray([$original_data, $this->moduleOverrides], TRUE);
-      }
-      if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
-        $original_data = NestedArray::mergeDeepArray([$original_data, $this->settingsOverrides], TRUE);
-      }
+      $original_data = $this->mergeOverridesWithData($original_data);
     }
 
-    if (empty($key)) {
-      return $original_data;
+    return self::extractKeyedData($original_data, $key);
+  }
+
+  /**
+   * Merge module and settings overrides with the provided data.
+   *
+   * @param array $data
+   *   The data to merge the overrides with.
+   *
+   * @return array
+   *   The overwritten data, unchanged if no overrides apply.
+   */
+  protected function mergeOverridesWithData(array $data) {
+    if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
+      $data = NestedArray::mergeDeepArray([$data, $this->moduleOverrides], TRUE);
     }
-    else {
-      $parts = explode('.', $key);
-      if (count($parts) == 1) {
-        return isset($original_data[$key]) ? $original_data[$key] : NULL;
-      }
-      else {
-        $value = NestedArray::getValue($original_data, $parts, $key_exists);
-        return $key_exists ? $value : NULL;
-      }
+    if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
+      $data = NestedArray::mergeDeepArray([$data, $this->settingsOverrides], TRUE);
     }
+    return $data;
   }
 
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigBase.php b/core/lib/Drupal/Core/Config/ConfigBase.php
index 4f445ea21c..64f348a9a7 100644
--- a/core/lib/Drupal/Core/Config/ConfigBase.php
+++ b/core/lib/Drupal/Core/Config/ConfigBase.php
@@ -129,19 +129,7 @@ public static function validateName($name) {
    *   The data that was requested.
    */
   public function get($key = '') {
-    if (empty($key)) {
-      return $this->data;
-    }
-    else {
-      $parts = explode('.', $key);
-      if (count($parts) == 1) {
-        return isset($this->data[$key]) ? $this->data[$key] : NULL;
-      }
-      else {
-        $value = NestedArray::getValue($this->data, $parts, $key_exists);
-        return $key_exists ? $value : NULL;
-      }
-    }
+    return self::extractKeyedData($this->data, $key);
   }
 
   /**
@@ -295,4 +283,33 @@ protected function castSafeStrings($data) {
     return $data;
   }
 
+  /**
+   * Extract the value of a sub key in the data.
+   *
+   * @param array $data
+   *   The configuration data.
+   * @param string $key
+   *   A string that maps to a key within the configuration data.
+   *
+   * @return mixed
+   *   The data at the key or NULL if it is not set.
+   *
+   * @see \Drupal\Core\Config\ConfigBase::get
+   */
+  protected static function extractKeyedData(array $data, $key) {
+    if (empty($key)) {
+      return $data;
+    }
+    else {
+      $parts = explode('.', $key);
+      if (count($parts) == 1) {
+        return isset($data[$key]) ? $data[$key] : NULL;
+      }
+      else {
+        $value = NestedArray::getValue($data, $parts, $key_exists);
+        return $key_exists ? $value : NULL;
+      }
+    }
+  }
+
 }
diff --git a/core/modules/settings_tray/js/settings_tray.es6.js b/core/modules/settings_tray/js/settings_tray.es6.js
index a680115490..c182a873ed 100644
--- a/core/modules/settings_tray/js/settings_tray.es6.js
+++ b/core/modules/settings_tray/js/settings_tray.es6.js
@@ -5,7 +5,7 @@
  * @private
  */
 
-(function ($, Drupal) {
+(function ($, Drupal, drupalSettings) {
   const blockConfigureSelector = '[data-settings-tray-edit]';
   const toggleEditSelector = '[data-drupal-settingstray="toggle"]';
   const itemsToToggleSelector = '[data-off-canvas-main-canvas], #toolbar-bar, [data-drupal-settingstray="editable"] a, [data-drupal-settingstray="editable"] button';
@@ -164,6 +164,17 @@
         if (!('dialogOptions' in instance.options.data)) {
           instance.options.data.dialogOptions = {};
         }
+
+        if (drupalSettings.hasOwnProperty('settings_tray') && drupalSettings.settings_tray.hasOwnProperty('overridden_blocks')) {
+          Object.entries(drupalSettings.settings_tray.overridden_blocks).forEach(
+            ([blockId, url]) => {
+              if (instance.options.url.includes(`/${blockId}/`)) {
+                instance.options.url = url;
+              }
+            },
+          );
+        }
+
         instance.options.data.dialogOptions.settingsTrayActiveEditableId = $(instance.element).parents('.settings-tray-editable').attr('id');
         instance.progress = { type: 'fullscreen' };
       });
@@ -253,4 +264,4 @@
       }
     },
   });
-}(jQuery, Drupal));
+}(jQuery, Drupal, drupalSettings));
diff --git a/core/modules/settings_tray/js/settings_tray.js b/core/modules/settings_tray/js/settings_tray.js
index 78c5b60382..98e81f3d93 100644
--- a/core/modules/settings_tray/js/settings_tray.js
+++ b/core/modules/settings_tray/js/settings_tray.js
@@ -4,8 +4,9 @@
 * https://www.drupal.org/node/2815083
 * @preserve
 **/
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
 
-(function ($, Drupal) {
+(function ($, Drupal, drupalSettings) {
   var blockConfigureSelector = '[data-settings-tray-edit]';
   var toggleEditSelector = '[data-drupal-settingstray="toggle"]';
   var itemsToToggleSelector = '[data-off-canvas-main-canvas], #toolbar-bar, [data-drupal-settingstray="editable"] a, [data-drupal-settingstray="editable"] button';
@@ -100,6 +101,19 @@
       if (!('dialogOptions' in instance.options.data)) {
         instance.options.data.dialogOptions = {};
       }
+
+      if (drupalSettings.hasOwnProperty('settings_tray') && drupalSettings.settings_tray.hasOwnProperty('overridden_blocks')) {
+        Object.entries(drupalSettings.settings_tray.overridden_blocks).forEach(function (_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+              blockId = _ref2[0],
+              url = _ref2[1];
+
+          if (instance.options.url.includes('/' + blockId + '/')) {
+            instance.options.url = url;
+          }
+        });
+      }
+
       instance.options.data.dialogOptions.settingsTrayActiveEditableId = $(instance.element).parents('.settings-tray-editable').attr('id');
       instance.progress = { type: 'fullscreen' };
     });
@@ -153,4 +167,4 @@
       }
     }
   });
-})(jQuery, Drupal);
\ No newline at end of file
+})(jQuery, Drupal, drupalSettings);
\ No newline at end of file
diff --git a/core/modules/settings_tray/settings_tray.libraries.yml b/core/modules/settings_tray/settings_tray.libraries.yml
index de5c82c78d..11b55a478f 100644
--- a/core/modules/settings_tray/settings_tray.libraries.yml
+++ b/core/modules/settings_tray/settings_tray.libraries.yml
@@ -17,3 +17,4 @@ drupal.settings_tray:
     - core/drupal
     - core/jquery.once
     - core/drupal.ajax
+    - core/drupalSettings
diff --git a/core/modules/settings_tray/settings_tray.module b/core/modules/settings_tray/settings_tray.module
index af04450459..821f62c19c 100644
--- a/core/modules/settings_tray/settings_tray.module
+++ b/core/modules/settings_tray/settings_tray.module
@@ -10,6 +10,9 @@
 use Drupal\settings_tray\Block\BlockEntityOffCanvasForm;
 use Drupal\settings_tray\Form\SystemBrandingOffCanvasForm;
 use Drupal\settings_tray\Form\SystemMenuOffCanvasForm;
+use Drupal\block\Entity\Block;
+use Drupal\Core\Url;
+use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 
 /**
  * Implements hook_help().
@@ -48,6 +51,21 @@ function settings_tray_contextual_links_view_alter(&$element, $items) {
   }
 }
 
+/**
+ * Checks if a block has overrides.
+ *
+ * @param string $block_id
+ *   The ID of the block to check for overrides.
+ *
+ * @return bool
+ *   TRUE if the block has overrides otherwise FALSE.
+ */
+function _settings_tray_has_block_overrides($block_id) {
+  $block = Block::load($block_id);
+  $overrides = \Drupal::config($block->getEntityType()->getConfigPrefix() . '.' . $block->id())->getOverrides();
+  return !empty($overrides);
+}
+
 /**
  * Implements hook_block_view_alter().
  */
@@ -58,6 +76,27 @@ function settings_tray_block_view_alter(array &$build) {
   $build['#contextual_links']['settings_tray'] = [
     'route_parameters' => [],
   ];
+  $block_id = $build['#block']->id();
+  // If a block currently has configuration overrides it cannot be edited in the
+  // Settings Tray form.
+  if (_settings_tray_has_block_overrides($block_id)) {
+    $url = Url::fromRoute('settings_tray.overridden_block_warning')
+      ->setRouteParameter('block', $block_id)
+      ->setOptions(
+        [
+          'query' => [
+            MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog.off_canvas',
+          ] + \Drupal::destination()->getAsArray(),
+        ]
+      );
+    // Store the URL to the overridden notice for this block in drupalSettings.
+    // This will be used in the Javascript function prepareAjaxLinks() to
+    // replace the URL to the Settings Tray edit form. We cannot use
+    // settings_tray_contextual_links_view_alter() to alter the URL because the
+    // contextual links will not be rebuilt for every context that could have
+    // configuration overrides.
+    $build['#attached']['drupalSettings']['settings_tray']['overridden_blocks'][$block_id] = $url->toString();
+  }
 }
 
 /**
diff --git a/core/modules/settings_tray/settings_tray.routing.yml b/core/modules/settings_tray/settings_tray.routing.yml
index 01109e4c79..c2f4f7c140 100644
--- a/core/modules/settings_tray/settings_tray.routing.yml
+++ b/core/modules/settings_tray/settings_tray.routing.yml
@@ -6,3 +6,10 @@ entity.block.off_canvas_form:
   requirements:
     _permission: 'administer blocks'
     _access_block_plugin_has_settings_tray_form: 'TRUE'
+settings_tray.overridden_block_warning:
+  path: '/admin/settings-tray-overridden/{block}'
+  defaults:
+    _controller: '\Drupal\settings_tray\Controller\OverriddenBlockConfig::overrideNotice'
+    _title_callback: '\Drupal\settings_tray\Block\BlockEntityOffCanvasForm::title'
+  requirements:
+    _permission: 'administer blocks'
diff --git a/core/modules/settings_tray/src/Controller/OverriddenBlockConfig.php b/core/modules/settings_tray/src/Controller/OverriddenBlockConfig.php
new file mode 100644
index 0000000000..f113f82070
--- /dev/null
+++ b/core/modules/settings_tray/src/Controller/OverriddenBlockConfig.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Drupal\settings_tray\Controller;
+
+use Drupal\block\BlockInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Url;
+
+/**
+ * Controller to display overridden block notice and edit link.
+ *
+ * Overridden blocks cannot be overridden in Settings Tray functionality
+ * because there is not uniform method for edit any potential configuration
+ * override.
+ *
+ * @see
+ */
+class OverriddenBlockConfig {
+
+  use StringTranslationTrait;
+
+  /**
+   * Provides a notice for overridden blocks and a link to edit them.
+   *
+   * @param \Drupal\block\BlockInterface $block
+   *   The block that is overridden.
+   *
+   * @return array
+   *   The render array for the notice and block edit link.
+   */
+  public function overrideNotice(BlockInterface $block) {
+    return [
+      'message' => [
+        '#type' => 'markup',
+        '#markup' => '<p>' . $this->t('This block cannot be edited in the Settings Tray form because it has configuration overrides in effect.') . '</p>',
+      ],
+      'link' => [
+        '#type' => 'link',
+        '#title' => $this->t('Edit Block'),
+        '#url' => Url::fromRoute('entity.block.edit_form')
+          ->setRouteParameter('block', $block->id())
+          ->setOption('query', ['destination' => \Drupal::request()->get('destination')]),
+      ],
+    ];
+
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Config/ConfigTest.php b/core/tests/Drupal/Tests/Core/Config/ConfigTest.php
index 41c3e93c99..8633e59fed 100644
--- a/core/tests/Drupal/Tests/Core/Config/ConfigTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/ConfigTest.php
@@ -173,6 +173,7 @@ public function testSaveExisting($data) {
    * @covers ::setModuleOverride
    * @covers ::setSettingsOverride
    * @covers ::getOriginal
+   * @covers ::getOverrides
    * @dataProvider overrideDataProvider
    */
   public function testOverrideData($data, $module_data, $setting_data) {
@@ -184,26 +185,37 @@ public function testOverrideData($data, $module_data, $setting_data) {
 
     // Save so that the original data is stored.
     $this->config->save();
+    $this->assertNull($this->config->getOverrides());
 
     // Set module override data and check value before and after save.
     $this->config->setModuleOverride($module_data);
     $this->assertConfigDataEquals($module_data);
+    $this->assertEquals($module_data, $this->config->getOverrides());
     $this->config->save();
     $this->assertConfigDataEquals($module_data);
+    $this->assertEquals($module_data, $this->config->getOverrides());
+
+    // Reset the module overrides.
+    $this->config->setModuleOverride([]);
+    $this->assertNull($this->config->getOverrides());
 
     // Set setting override data and check value before and after save.
     $this->config->setSettingsOverride($setting_data);
     $this->assertConfigDataEquals($setting_data);
+    $this->assertEquals($setting_data, $this->config->getOverrides());
     $this->config->save();
     $this->assertConfigDataEquals($setting_data);
+    $this->assertEquals($setting_data, $this->config->getOverrides());
 
     // Set module overrides again to ensure override order is correct.
     $this->config->setModuleOverride($module_data);
 
     // Setting data should be overriding module data.
     $this->assertConfigDataEquals($setting_data);
+    $this->assertEquals($setting_data, $this->config->getOverrides());
     $this->config->save();
     $this->assertConfigDataEquals($setting_data);
+    $this->assertEquals($setting_data, $this->config->getOverrides());
 
     // Check original data has not changed.
     $this->assertOriginalConfigDataEquals($data, FALSE);
@@ -215,7 +227,17 @@ public function testOverrideData($data, $module_data, $setting_data) {
     foreach ($setting_data as $key => $value) {
       $config_value = $this->config->getOriginal($key);
       $this->assertEquals($value, $config_value);
+      $this->assertEquals($value, $this->config->getOverrides($key));
     }
+
+    // Check that the overrides can be completely reset.
+    $this->config->setModuleOverride([]);
+    $this->config->setSettingsOverride([]);
+    $this->assertConfigDataEquals($data);
+    $this->assertNull($this->config->getOverrides());
+    $this->config->save();
+    $this->assertConfigDataEquals($data);
+    $this->assertNull($this->config->getOverrides());
   }
 
   /**
