diff --git a/core/modules/ckeditor/ckeditor.module b/core/modules/ckeditor/ckeditor.module
index 5105e173236360fbc2a31158f9dc54ca69d96030..babe27555e1a4b2917599d4e8c540456b64347d2 100644
--- a/core/modules/ckeditor/ckeditor.module
+++ b/core/modules/ckeditor/ckeditor.module
@@ -10,8 +10,11 @@
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\ckeditor\CKEditorPluginButtonsInterface;
+use Drupal\ckeditor\CKEditorPluginContextualInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\editor\Entity\Editor;
+use Drupal\editor\EditorInterface;
 
 /**
  * Implements hook_help().
@@ -122,6 +125,59 @@ function _ckeditor_theme_css($theme = NULL) {
   return $css;
 }
 
+/**
+ * Gets all enabled CKEditor 4 plugins.
+ *
+ * @param \Drupal\editor\EditorInterface $editor
+ *   A text editor config entity configured to use CKEditor 4.
+ *
+ * @return string[]
+ *   The enabled CKEditor 4 plugin IDs.
+ *
+ * @internal
+ */
+function _ckeditor_get_enabled_plugins(EditorInterface $editor): array {
+  assert($editor->getEditor() === 'ckeditor');
+
+  $cke4_plugin_manager = \Drupal::service('plugin.manager.ckeditor.plugin');
+
+  // This is largely copied from the CKEditor 4 plugin manager, because it
+  // unfortunately does not provide the API this needs.
+  // @see \Drupal\ckeditor\CKEditorPluginManager::getEnabledPluginFiles()
+  $plugins = array_keys($cke4_plugin_manager->getDefinitions());
+  $toolbar_buttons = $cke4_plugin_manager->getEnabledButtons($editor);
+  $enabled_plugins = [];
+  $additional_plugins = [];
+  foreach ($plugins as $plugin_id) {
+    $plugin = $cke4_plugin_manager->createInstance($plugin_id);
+
+    $enabled = FALSE;
+    // Plugin is enabled if it provides a button that has been enabled.
+    if ($plugin instanceof CKEditorPluginButtonsInterface) {
+      $plugin_buttons = array_keys($plugin->getButtons());
+      $enabled = (count(array_intersect($toolbar_buttons, $plugin_buttons)) > 0);
+    }
+    // Otherwise plugin is enabled if it declares itself as enabled.
+    if (!$enabled && $plugin instanceof CKEditorPluginContextualInterface) {
+      $enabled = $plugin->isEnabled($editor);
+    }
+
+    if ($enabled) {
+      $enabled_plugins[$plugin_id] = $plugin_id;
+      // Check if this plugin has dependencies that should be considered
+      // enabled.
+      $additional_plugins = array_merge($additional_plugins, array_diff($plugin->getDependencies($editor), $additional_plugins));
+    }
+  }
+
+  // Add the list of dependent plugins.
+  foreach ($additional_plugins as $plugin_id) {
+    $enabled_plugins[$plugin_id] = $plugin_id;
+  }
+
+  return $enabled_plugins;
+}
+
 /**
  * Implements hook_library_info_alter().
  */
@@ -203,3 +259,34 @@ function ckeditor_filter_format_edit_form_validate($form, FormStateInterface $fo
     }
   }
 }
+
+/**
+ * Implements hook_ENTITY_TYPE_presave().
+ */
+function ckeditor_editor_presave(EditorInterface $editor) {
+  // Only try to update editors using CKEditor 4.
+  if ($editor->getEditor() !== 'ckeditor') {
+    return FALSE;
+  }
+
+  $enabled_plugins = _ckeditor_get_enabled_plugins($editor);
+
+  // Only update if the editor has plugin settings for disabled plugins.
+  $needs_update = FALSE;
+  $settings = $editor->getSettings();
+
+  // Updates are not needed if plugin settings are not defined for the editor.
+  if (!isset($settings['plugins'])) {
+    return;
+  }
+
+  foreach (array_keys($settings['plugins']) as $plugin_id) {
+    if (!in_array($plugin_id, $enabled_plugins, TRUE)) {
+      unset($settings['plugins'][$plugin_id]);
+      $needs_update = TRUE;
+    }
+  }
+  if ($needs_update) {
+    $editor->setSettings($settings);
+  }
+}
diff --git a/core/modules/ckeditor/ckeditor.post_update.php b/core/modules/ckeditor/ckeditor.post_update.php
new file mode 100644
index 0000000000000000000000000000000000000000..224b5280d2909d33f133621c7a4226161b12cea1
--- /dev/null
+++ b/core/modules/ckeditor/ckeditor.post_update.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for CKEditor.
+ */
+
+use Drupal\Core\Config\Entity\ConfigEntityUpdater;
+use Drupal\editor\Entity\Editor;
+
+/**
+ * Updates Text Editors using CKEditor 4 to omit settings for disabled plugins.
+ */
+function ckeditor_post_update_omit_settings_for_disabled_plugins(&$sandbox = []) {
+  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
+  $config_entity_updater->update($sandbox, 'editor', function (Editor $editor): bool {
+    // Only try to update editors using CKEditor 4.
+    if ($editor->getEditor() !== 'ckeditor') {
+      return FALSE;
+    }
+
+    $enabled_plugins = _ckeditor_get_enabled_plugins($editor);
+
+    // Only update if the editor has plugin settings for disabled plugins.
+    $needs_update = FALSE;
+    $settings = $editor->getSettings();
+
+    // Updates are not needed if plugin settings are not defined for the editor.
+    if (!isset($settings['plugins'])) {
+      return FALSE;
+    }
+
+    foreach (array_keys($settings['plugins']) as $plugin_id) {
+      if (!in_array($plugin_id, $enabled_plugins, TRUE)) {
+        $needs_update = TRUE;
+      }
+    }
+
+    return $needs_update;
+  });
+}
diff --git a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
index 9d36a8e9667c26c1fe91b4c97262b3633997bd5f..0e43f969e499ff35af18cd0e04ee0f417cf9f4e6 100644
--- a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
+++ b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
@@ -166,7 +166,7 @@ public function getDefaultSettings() {
           ],
         ],
       ],
-      'plugins' => ['language' => ['language_list' => 'un']],
+      'plugins' => [],
     ];
   }
 
@@ -287,6 +287,24 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
     if ($form_state->hasValue('plugins')) {
       $form_state->unsetValue('plugin_settings');
     }
+
+    // Ensure plugin settings are only saved for plugins that are actually
+    // enabled.
+    $about_to_be_saved_editor = Editor::create([
+      'editor' => 'ckeditor',
+      'settings' => [
+        'toolbar' => $form_state->getValue('toolbar'),
+        'plugins' => $form_state->getValue('plugins'),
+      ],
+    ]);
+    $enabled_plugins = _ckeditor_get_enabled_plugins($about_to_be_saved_editor);
+    $plugin_settings = $form_state->getValue('plugins', []);
+    foreach (array_keys($plugin_settings) as $plugin_id) {
+      if (!in_array($plugin_id, $enabled_plugins, TRUE)) {
+        unset($plugin_settings[$plugin_id]);
+      }
+    }
+    $form_state->setValue('plugins', $plugin_settings);
   }
 
   /**
diff --git a/core/modules/ckeditor/tests/src/Functional/CKEditorAdminTest.php b/core/modules/ckeditor/tests/src/Functional/CKEditorAdminTest.php
index 686d7da6d6b4e1b9796e787e2708c93d71a08179..ded1d54c79f1384ad33ef9c48af11cdfb72ea672 100644
--- a/core/modules/ckeditor/tests/src/Functional/CKEditorAdminTest.php
+++ b/core/modules/ckeditor/tests/src/Functional/CKEditorAdminTest.php
@@ -108,7 +108,7 @@ public function testExistingFormat() {
           ],
         ],
       ],
-      'plugins' => ['language' => ['language_list' => 'un']],
+      'plugins' => [],
     ];
     $this->assertEquals($expected_default_settings, $ckeditor->getDefaultSettings());
 
@@ -136,22 +136,27 @@ public function testExistingFormat() {
     $expected_buttons_value = json_encode($expected_default_settings['toolbar']['rows']);
     $this->assertSession()->fieldValueEquals('editor[settings][toolbar][button_groups]', $expected_buttons_value);
 
-    // Ensure the styles textarea exists and is initialized empty.
-    $this->assertSession()->fieldValueEquals('editor[settings][plugins][stylescombo][styles]', '');
-
     // Submit the form to save the selection of CKEditor as the chosen editor.
     $this->submitForm($edit, 'Save configuration');
 
     // Ensure an Editor object exists now, with the proper settings.
     $expected_settings = $expected_default_settings;
-    $expected_settings['plugins']['stylescombo']['styles'] = '';
     $editor = Editor::load('filtered_html');
     $this->assertInstanceOf(Editor::class, $editor);
     $this->assertEquals($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
 
     // Configure the Styles plugin, and ensure the updated settings are saved.
     $this->drupalGet('admin/config/content/formats/manage/filtered_html');
+
+    // Ensure the styles textarea exists and is initialized empty.
+    $this->assertSession()->fieldValueEquals('editor[settings][plugins][stylescombo][styles]', '');
+
+    $expected_settings['toolbar']['rows'][0][] = [
+      'name' => 'Styles dropdown',
+      'items' => ['Styles'],
+    ];
     $edit = [
+      'editor[settings][toolbar][button_groups]' => json_encode($expected_settings['toolbar']['rows']),
       'editor[settings][plugins][stylescombo][styles]' => "h1.title|Title\np.callout|Callout\n\n",
     ];
     $this->submitForm($edit, 'Save configuration');
@@ -164,6 +169,7 @@ public function testExistingFormat() {
     // done via drag and drop, but here we can only emulate the end result of
     // that interaction). Test multiple toolbar rows and a divider within a row.
     $this->drupalGet('admin/config/content/formats/manage/filtered_html');
+    $expected_settings = $expected_default_settings;
     $expected_settings['toolbar']['rows'][0][] = [
       'name' => 'Action history',
       'items' => ['Undo', '|', 'Redo', 'JustifyCenter'],
@@ -205,7 +211,12 @@ public function testExistingFormat() {
 
     // Finally, check the "Ultra llama mode" checkbox.
     $this->drupalGet('admin/config/content/formats/manage/filtered_html');
+    $expected_settings['toolbar']['rows'][0][] = [
+      'name' => 'Ultra llama mode',
+      'items' => ['Llama'],
+    ];
     $edit = [
+      'editor[settings][toolbar][button_groups]' => json_encode($expected_settings['toolbar']['rows']),
       'editor[settings][plugins][llama_contextual_and_button][ultra_llama_mode]' => '1',
     ];
     $this->submitForm($edit, 'Save configuration');
@@ -287,7 +298,6 @@ public function testNewFormat() {
 
     // Ensure an Editor object exists now, with the proper settings.
     $expected_settings = $default_settings;
-    $expected_settings['plugins']['stylescombo']['styles'] = '';
     $editor = Editor::load('amazing_format');
     $this->assertInstanceOf(Editor::class, $editor);
     $this->assertEquals($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
diff --git a/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboAdminTest.php b/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboAdminTest.php
index 44444d089de446d75dbc571ddfb7ef8e2a17ff10..10ef5c3163925991592e1d8bcb3a829766816920 100644
--- a/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboAdminTest.php
+++ b/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboAdminTest.php
@@ -39,6 +39,13 @@ class CKEditorStylesComboAdminTest extends BrowserTestBase {
    */
   protected $format;
 
+  /**
+   * The default editor settings.
+   *
+   * @var array
+   */
+  protected $defaultSettings;
+
   /**
    * {@inheritdoc}
    */
@@ -52,9 +59,16 @@ protected function setUp(): void {
       'filters' => [],
     ]);
     $filter_format->save();
+    $ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor');
+    $this->defaultSettings = $ckeditor->getDefaultSettings();
+    $this->defaultSettings['toolbar']['rows'][0][] = [
+      'name' => 'Styles dropdown',
+      'items' => ['Styles'],
+    ];
     $editor = Editor::create([
       'format' => $this->format,
       'editor' => 'ckeditor',
+      'settings' => $this->defaultSettings,
     ]);
     $editor->save();
 
@@ -65,14 +79,11 @@ protected function setUp(): void {
    * Tests StylesCombo settings for an existing text format.
    */
   public function testExistingFormat() {
-    $ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor');
-    $default_settings = $ckeditor->getDefaultSettings();
-
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('admin/config/content/formats/manage/' . $this->format);
 
     // Ensure an Editor config entity exists, with the proper settings.
-    $expected_settings = $default_settings;
+    $expected_settings = $this->defaultSettings;
     $editor = Editor::load($this->format);
     $this->assertEquals($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
 
diff --git a/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboTranslationTest.php b/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboTranslationTest.php
index b79d0fe81b308448e577e97cf00548e641bf1f20..0e4cba82e1b23b83d30d963d2145364fe2d98e2f 100644
--- a/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboTranslationTest.php
+++ b/core/modules/ckeditor/tests/src/Functional/CKEditorStylesComboTranslationTest.php
@@ -51,9 +51,16 @@ protected function setUp(): void {
       'filters' => [],
     ]);
     $filter_format->save();
+    $ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor');
+    $settings = $ckeditor->getDefaultSettings();
+    $settings['toolbar']['rows'][0][] = [
+      'name' => 'Styles dropdown',
+      'items' => ['Styles'],
+    ];
     $editor = Editor::create([
       'format' => $this->format,
       'editor' => 'ckeditor',
+      'settings' => $settings,
     ]);
     $editor->save();
 
diff --git a/core/modules/ckeditor/tests/src/Functional/Update/CKEditorUpdateOmitDisabledPluginSettings.php b/core/modules/ckeditor/tests/src/Functional/Update/CKEditorUpdateOmitDisabledPluginSettings.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ef124828282b14ac811cc8640efd6ea618ff37d
--- /dev/null
+++ b/core/modules/ckeditor/tests/src/Functional/Update/CKEditorUpdateOmitDisabledPluginSettings.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Drupal\Tests\ckeditor\Functional\Update;
+
+use Drupal\editor\Entity\Editor;
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * Tests the update path for CKEditor plugin settings for disabled plugins.
+ *
+ * @group Update
+ */
+class CKEditorUpdateOmitDisabledPluginSettings extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-9.3.0.filled.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Ensure settings for disabled CKEditor 4 plugins are omitted on post update.
+   */
+  public function testUpdateUpdateOmitDisabledSettingsPostUpdate() {
+    $editor = Editor::load('basic_html');
+    $settings = $editor->getSettings();
+    $this->assertArrayHasKey('stylescombo', $settings['plugins']);
+
+    $this->runUpdates();
+
+    $editor = Editor::load('basic_html');
+    $settings = $editor->getSettings();
+    $this->assertArrayNotHasKey('stylescombo', $settings['plugins']);
+  }
+
+  /**
+   * Ensure settings for disabled CKEditor 4 plugins are omitted on entity save.
+   */
+  public function testUpdateUpdateOmitDisabledSettingsEntitySave() {
+    $editor = Editor::load('basic_html');
+    $settings = $editor->getSettings();
+    $this->assertArrayHasKey('stylescombo', $settings['plugins']);
+    $editor->save();
+
+    $editor = Editor::load('basic_html');
+    $settings = $editor->getSettings();
+    $this->assertArrayNotHasKey('stylescombo', $settings['plugins']);
+  }
+
+}
diff --git a/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php b/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php
index 408ff20c9e65fb7dbcc27fce7c97b6e2ec3a9776..f7aeaf253d7c2d635b746f951bc095dfcc4d77a7 100644
--- a/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php
+++ b/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php
@@ -297,32 +297,6 @@ protected function setUp(): void {
       ],
     ])->save();
 
-    FilterFormat::create([
-      'format' => 'cke4_plugins_with_settings_for_disabled_plugins',
-      'name' => 'All CKEditor 4 core plugins with settings for disabled plugins',
-    ])->save();
-    Editor::create([
-      'format' => 'cke4_plugins_with_settings_for_disabled_plugins',
-      'editor' => 'ckeditor',
-      'settings' => [
-        // Empty toolbar.
-        'toolbar' => [
-          'rows' => [
-            0 => [
-              [
-                'name' => 'Only buttons without settings',
-                'items' => [
-                  'Bold',
-                ],
-              ],
-            ],
-          ],
-        ],
-        // Same plugin settings as `cke4_plugins_with_settings`.
-        'plugins' => Editor::load('cke4_plugins_with_settings')->getSettings()['plugins'],
-      ],
-    ])->save();
-
     FilterFormat::create([
       'format' => 'cke4_contrib_plugins_now_in_core',
       'name' => 'All CKEditor 4 contrib plugins now in core',
@@ -1097,26 +1071,6 @@ public function provider() {
       ],
     ];
 
-    yield "cke4_plugins_with_settings_for_disabled_plugins can be switched to CKEditor 5 without problems; irrelevant settings are dropped" => [
-      'format_id' => 'cke4_plugins_with_settings_for_disabled_plugins',
-      'filters_to_drop' => [],
-      'expected_ckeditor5_settings' => [
-        'toolbar' => [
-          'items' => [
-            'bold',
-          ],
-        ],
-        'plugins' => [],
-      ],
-      'expected_superset' => '',
-      'expected_fundamental_compatibility_violations' => [],
-      'expected_messages' => [
-        'warning' => [
-          'The <em class="placeholder">llama_contextual_and_button</em> plugin settings do not have a known upgrade path.',
-        ],
-      ],
-    ];
-
     yield "cke4_contrib_plugins_now_in_core can be switched to CKEditor 5 without problems" => [
       'format_id' => 'cke4_contrib_plugins_now_in_core',
       'filters_to_drop' => [],
diff --git a/core/profiles/demo_umami/config/install/editor.editor.basic_html.yml b/core/profiles/demo_umami/config/install/editor.editor.basic_html.yml
index 4ae2bffdcc413576a622fb3ecd94c3dba1396529..62138b8768ef1eaa487f4720152326320c73886c 100644
--- a/core/profiles/demo_umami/config/install/editor.editor.basic_html.yml
+++ b/core/profiles/demo_umami/config/install/editor.editor.basic_html.yml
@@ -39,11 +39,7 @@ settings:
           name: Tools
           items:
             - Source
-  plugins:
-    language:
-      language_list: un
-    stylescombo:
-      styles: ''
+  plugins: {}
 image_upload:
   status: false
   scheme: public
diff --git a/core/profiles/demo_umami/config/install/editor.editor.full_html.yml b/core/profiles/demo_umami/config/install/editor.editor.full_html.yml
index c0f60d273c44784bed385bdfd1fa751671a5b2a8..0f40656b7c514420bc5dc7e0d8555c5d8043d3a4 100644
--- a/core/profiles/demo_umami/config/install/editor.editor.full_html.yml
+++ b/core/profiles/demo_umami/config/install/editor.editor.full_html.yml
@@ -47,11 +47,7 @@ settings:
           items:
             - ShowBlocks
             - Source
-  plugins:
-    language:
-      language_list: un
-    stylescombo:
-      styles: ''
+  plugins: {}
 image_upload:
   status: true
   scheme: public
diff --git a/core/profiles/standard/config/install/editor.editor.basic_html.yml b/core/profiles/standard/config/install/editor.editor.basic_html.yml
index 966cec6a19fbefa365bfecc6021c4f866b2962e9..cafc88e22c9108d9ccebf52be7837667b5e504d3 100644
--- a/core/profiles/standard/config/install/editor.editor.basic_html.yml
+++ b/core/profiles/standard/config/install/editor.editor.basic_html.yml
@@ -39,9 +39,7 @@ settings:
           name: Tools
           items:
             - Source
-  plugins:
-    stylescombo:
-      styles: ''
+  plugins: {}
 image_upload:
   status: true
   scheme: public
diff --git a/core/profiles/standard/config/install/editor.editor.full_html.yml b/core/profiles/standard/config/install/editor.editor.full_html.yml
index f5dd7bcc170b2848ea1c1ef0d9d413ff7f4b6100..a423369d1f5cc78e27ad3ad9c5dcde88fb711317 100644
--- a/core/profiles/standard/config/install/editor.editor.full_html.yml
+++ b/core/profiles/standard/config/install/editor.editor.full_html.yml
@@ -47,9 +47,7 @@ settings:
           items:
             - ShowBlocks
             - Source
-  plugins:
-    stylescombo:
-      styles: ''
+  plugins: {}
 image_upload:
   status: true
   scheme: public