diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
index 95ba15a38a359057dbcf3a36cdb8e2b51248688b..147ef492ed70b862bdbdc7b3eff13d9bf20d600a 100644
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitManager.php
@@ -105,4 +105,19 @@ public function getAvailableToolkits() {
     return $output;
   }
 
+  /**
+   * Returns all valid extensions.
+   *
+   * @return string[]
+   *   All possible valid extensions.
+   *
+   * @see \Drupal\image\Plugin\ImageEffect\ConvertImageEffect::buildConfigurationForm()
+   *
+   * @internal
+   * @todo Revisit in https://www.drupal.org/node/3446364
+   */
+  public static function getAllValidExtensions(): array {
+    return \Drupal::service('image.toolkit.manager')->getDefaultToolkit()->getSupportedExtensions();
+  }
+
 }
diff --git a/core/modules/image/config/schema/image.data_types.schema.yml b/core/modules/image/config/schema/image.data_types.schema.yml
index 9e4b9e1c1606629f419efd2440e1f8d906929291..121bf0f1f934b89fa15339ed62fe7462fad758f9 100644
--- a/core/modules/image/config/schema/image.data_types.schema.yml
+++ b/core/modules/image/config/schema/image.data_types.schema.yml
@@ -2,13 +2,23 @@
 
 image_size:
   type: mapping
+  constraints:
+    FullyValidatable: ~
   mapping:
     width:
       type: integer
       label: 'Width'
+      nullable: true
+      constraints:
+        NotBlank:
+          allowNull: true
     height:
       type: integer
       label: 'Height'
+      nullable: true
+      constraints:
+        NotBlank:
+          allowNull: true
 
 field_default_image:
   type: mapping
diff --git a/core/modules/image/config/schema/image.schema.yml b/core/modules/image/config/schema/image.schema.yml
index 428ba96648c49aaf7ab5e6a62b1c8eced84a5192..f805caa378ca822067e3fb36ddf1f9fe43a412b6 100644
--- a/core/modules/image/config/schema/image.schema.yml
+++ b/core/modules/image/config/schema/image.schema.yml
@@ -3,6 +3,8 @@
 image.style.*:
   type: config_entity
   label: 'Image style'
+  constraints:
+    FullyValidatable: ~
   mapping:
     name:
       type: machine_name
@@ -46,6 +48,9 @@ image.effect.image_convert:
     extension:
       label: 'Extension'
       type: string
+      constraints:
+        Choice:
+          callback: 'Drupal\Core\ImageToolkit\ImageToolkitManager::getAllValidExtensions'
 
 image.effect.image_resize:
   type: image_size
diff --git a/core/modules/image/tests/src/Functional/ImageEffect/ConvertTest.php b/core/modules/image/tests/src/Functional/ImageEffect/ConvertTest.php
index 3677a0f68b7d19819d26d22d091529a14c984bfb..6ca7b06955e98ee9b5ec6e96b5c172968bc37e77 100644
--- a/core/modules/image/tests/src/Functional/ImageEffect/ConvertTest.php
+++ b/core/modules/image/tests/src/Functional/ImageEffect/ConvertTest.php
@@ -37,6 +37,7 @@ public function testConvertFileInRoot() {
     $this->assertEquals(SAVED_NEW, $image_style->save());
     $image_style->addImageEffect([
       'id' => 'image_convert',
+      'weight' => 0,
       'data' => [
         'extension' => 'jpeg',
       ],
diff --git a/core/modules/image/tests/src/Kernel/ImageEffectsTest.php b/core/modules/image/tests/src/Kernel/ImageEffectsTest.php
index 08747b7a09d3f9558fd07fe0105c1713a0feb833..9d02930e097c841b6feeaef273f6e401553ad642 100644
--- a/core/modules/image/tests/src/Kernel/ImageEffectsTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageEffectsTest.php
@@ -229,7 +229,7 @@ public function testEffectFormValidationErrors() {
       'name' => 'foo',
       'label' => 'Foo',
     ]);
-    $effect_id = $image_style->addImageEffect(['id' => 'image_scale']);
+    $effect_id = $image_style->addImageEffect(['id' => 'image_scale', 'weight' => 0]);
     $image_style->save();
 
     $form = new ImageEffectEditForm();
diff --git a/core/modules/image/tests/src/Kernel/ImageImportTest.php b/core/modules/image/tests/src/Kernel/ImageImportTest.php
index ae6826eaf02c623c6814a50843415196e4504281..1f945f605b4a1209f400bc971f54d4a77730d0b4 100644
--- a/core/modules/image/tests/src/Kernel/ImageImportTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageImportTest.php
@@ -28,8 +28,8 @@ public function testImport() {
       'label' => 'Test',
     ]);
 
-    $style->addImageEffect(['id' => 'image_module_test_null']);
-    $style->addImageEffect(['id' => 'image_module_test_null']);
+    $style->addImageEffect(['id' => 'image_module_test_null', 'weight' => 0]);
+    $style->addImageEffect(['id' => 'image_module_test_null', 'weight' => 1]);
     $style->save();
 
     $this->assertCount(2, $style->getEffects());
@@ -38,6 +38,7 @@ public function testImport() {
     $style->set('effects', [
       $uuid => [
         'id' => 'image_module_test_null',
+        'weight' => 0,
       ],
     ]);
     $style->save();
diff --git a/core/modules/image/tests/src/Kernel/SettingsConfigValidationTest.php b/core/modules/image/tests/src/Kernel/SettingsConfigValidationTest.php
index 461a33bfb4148c3bf477cc1dc1ad737f4dead991..d62741a9ee6c3786ec526cdaea463407dce648a4 100644
--- a/core/modules/image/tests/src/Kernel/SettingsConfigValidationTest.php
+++ b/core/modules/image/tests/src/Kernel/SettingsConfigValidationTest.php
@@ -15,7 +15,7 @@ class SettingsConfigValidationTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['image'];
+  protected static $modules = ['image', 'system'];
 
   /**
    * Tests that the preview_image setting must be an existing image file.
diff --git a/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
index 484d143591696e356e18edeb3e82121c935a3936..3154872366d82f72afa3c82ad60593f466db8992 100644
--- a/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
@@ -430,6 +430,7 @@ public function testResponsiveImageFieldFormattersMultipleSources() {
     assert($large_style instanceof ImageStyleInterface);
     $large_style->addImageEffect([
       'id' => 'image_resize',
+      'weight' => 0,
       'data' => [
         'width' => '480',
         'height' => '480',
@@ -440,6 +441,7 @@ public function testResponsiveImageFieldFormattersMultipleSources() {
     assert($medium_style instanceof ImageStyleInterface);
     $medium_style->addImageEffect([
       'id' => 'image_resize',
+      'weight' => 0,
       'data' => [
         'width' => '220',
         'height' => '220',
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php
index 2e5c5d151955610e6657f84cc7d61d850f9264ec..90763605718ecd92970b6d113e9434bc7771e045 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php
@@ -227,7 +227,10 @@ public function testSchemaMapping() {
     $expected['mapping']['_core']['type'] = '_core_config_info';
     $expected['mapping']['_core']['requiredKey'] = FALSE;
     $expected['type'] = 'image.style.*';
-    $expected['constraints'] = ['ValidKeys' => '<infer>'];
+    $expected['constraints'] = [
+      'ValidKeys' => '<infer>',
+      'FullyValidatable' => NULL,
+    ];
 
     $this->assertEquals($expected, $definition);
 
@@ -241,12 +244,19 @@ public function testSchemaMapping() {
     $expected['unwrap_for_canonical_representation'] = TRUE;
     $expected['mapping']['width']['type'] = 'integer';
     $expected['mapping']['width']['label'] = 'Width';
+    $expected['mapping']['width']['nullable'] = TRUE;
+    $expected['mapping']['width']['constraints'] = ['NotBlank' => ['allowNull' => TRUE]];
     $expected['mapping']['height']['type'] = 'integer';
     $expected['mapping']['height']['label'] = 'Height';
+    $expected['mapping']['height']['nullable'] = TRUE;
+    $expected['mapping']['height']['constraints'] = ['NotBlank' => ['allowNull' => TRUE]];
     $expected['mapping']['upscale']['type'] = 'boolean';
     $expected['mapping']['upscale']['label'] = 'Upscale';
     $expected['type'] = 'image.effect.image_scale';
-    $expected['constraints'] = ['ValidKeys' => '<infer>'];
+    $expected['constraints'] = [
+      'ValidKeys' => '<infer>',
+      'FullyValidatable' => NULL,
+    ];
 
     $this->assertEquals($expected, $definition, 'Retrieved the right metadata for image.effect.image_scale');
 
@@ -259,6 +269,7 @@ public function testSchemaMapping() {
     $expected['mapping']['height']['requiredKey'] = TRUE;
     $expected['mapping']['upscale']['requiredKey'] = TRUE;
     $expected['requiredKey'] = TRUE;
+    $expected['required'] = TRUE;
 
     $this->assertEquals($expected, $definition, 'Retrieved the right metadata for the first effect of image.style.medium');