diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
index ce0e283c8efcd6d6c0a0555ddd9ac8a639a68e8e..1fba360804859092715015929993c0e2091e3da1 100644
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitBase.php
@@ -127,8 +127,14 @@ public function apply($operation, array $arguments = []) {
       $this->logger->error("The selected image handling toolkit '@toolkit' can not process operation '@operation'.", ['@toolkit' => $this->getPluginId(), '@operation' => $operation]);
       return FALSE;
     }
-    catch (\InvalidArgumentException $e) {
-      $this->logger->warning($e->getMessage(), []);
+    catch (\Throwable $t) {
+      $this->logger->warning("The image toolkit '@toolkit' failed processing '@operation' for image '@image'. Reported error: @class - @message", [
+        '@toolkit' => $this->getPluginId(),
+        '@operation' => $operation,
+        '@image' => $this->getSource(),
+        '@class' => get_class($t),
+        '@message' => $t->getMessage(),
+      ]);
       return FALSE;
     }
   }
diff --git a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationBase.php b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationBase.php
index dcc3b3d12134ab43ba5f35f10c9267549b4a674e..95b8a9c4f7884687969f5232d4a83eeee1bca928 100644
--- a/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationBase.php
+++ b/core/lib/Drupal/Core/ImageToolkit/ImageToolkitOperationBase.php
@@ -185,6 +185,9 @@ final public function apply(array $arguments) {
    *
    * @return bool
    *   TRUE if the operation was performed successfully, FALSE otherwise.
+   *
+   * @throws \RuntimeException
+   *   If the operation can not be performed.
    */
   abstract protected function execute(array $arguments);
 
diff --git a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
index 2753273a41327a7476341f9eeb126bcf4d4bb1cc..2abda1bdbecf3e356df0d216672c604c6971b840 100644
--- a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
+++ b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php
@@ -180,31 +180,54 @@ protected function load() {
       return FALSE;
     }
 
+    // Invalidate the image object and return if there's no function to load the
+    // image file.
     $function = 'imagecreatefrom' . image_type_to_extension($this->getType(), FALSE);
-    if (function_exists($function) && $resource = $function($this->getSource())) {
-      $this->setResource($resource);
-      if (imageistruecolor($resource)) {
-        return TRUE;
-      }
-      else {
-        // Convert indexed images to truecolor, copying the image to a new
-        // truecolor resource, so that filters work correctly and don't result
-        // in unnecessary dither.
-        $data = [
-          'width' => imagesx($resource),
-          'height' => imagesy($resource),
-          'extension' => image_type_to_extension($this->getType(), FALSE),
-          'transparent_color' => $this->getTransparentColor(),
-          'is_temp' => TRUE,
-        ];
-        if ($this->apply('create_new', $data)) {
-          imagecopy($this->getResource(), $resource, 0, 0, 0, 0, imagesx($resource), imagesy($resource));
-          imagedestroy($resource);
-        }
+    if (!function_exists($function)) {
+      $this->logger->error("The image toolkit '@toolkit' can not process image '@image'.", [
+        '@toolkit' => $this->getPluginId(),
+        '@image' => $this->getSource(),
+      ]);
+      $this->preLoadInfo = NULL;
+      return FALSE;
+    }
+
+    // Invalidate the image object and return if the load fails.
+    try {
+      $resource = $function($this->getSource());
+    }
+    catch (\Throwable $t) {
+      $this->logger->error("The image toolkit '@toolkit' failed loading image '@image'. Reported error: @class - @message", [
+        '@toolkit' => $this->getPluginId(),
+        '@image' => $this->getSource(),
+        '@class' => get_class($t),
+        '@message' => $t->getMessage(),
+      ]);
+      $this->preLoadInfo = NULL;
+      return FALSE;
+    }
+
+    $this->setResource($resource);
+    if (imageistruecolor($resource)) {
+      return TRUE;
+    }
+    else {
+      // Convert indexed images to truecolor, copying the image to a new
+      // truecolor resource, so that filters work correctly and don't result
+      // in unnecessary dither.
+      $data = [
+        'width' => imagesx($resource),
+        'height' => imagesy($resource),
+        'extension' => image_type_to_extension($this->getType(), FALSE),
+        'transparent_color' => $this->getTransparentColor(),
+        'is_temp' => TRUE,
+      ];
+      if ($this->apply('create_new', $data)) {
+        imagecopy($this->getResource(), $resource, 0, 0, 0, 0, imagesx($resource), imagesy($resource));
+        imagedestroy($resource);
       }
-      return (bool) $this->getResource();
     }
-    return FALSE;
+    return (bool) $this->getResource();
   }
 
   /**
@@ -236,7 +259,18 @@ public function save($destination) {
       return FALSE;
     }
     if ($this->getType() == IMAGETYPE_JPEG) {
-      $success = $function($this->getResource(), $destination, $this->configFactory->get('system.image.gd')->get('jpeg_quality'));
+      try {
+        $success = $function($this->getResource(), $destination, $this->configFactory->get('system.image.gd')->get('jpeg_quality'));
+      }
+      catch (\Throwable $t) {
+        $this->logger->error("The image toolkit '@toolkit' failed saving image '@image'. Reported error: @class - @message", [
+          '@toolkit' => $this->getPluginId(),
+          '@image' => $destination,
+          '@class' => get_class($t),
+          '@message' => $t->getMessage(),
+        ]);
+        $success = FALSE;
+      }
     }
     else {
       // Image types that support alpha need to be saved accordingly.
@@ -244,7 +278,18 @@ public function save($destination) {
         imagealphablending($this->getResource(), FALSE);
         imagesavealpha($this->getResource(), TRUE);
       }
-      $success = $function($this->getResource(), $destination);
+      try {
+        $success = $function($this->getResource(), $destination);
+      }
+      catch (\Throwable $t) {
+        $this->logger->error("The image toolkit '@toolkit' failed saving image '@image'. Reported error: @class - @message", [
+          '@toolkit' => $this->getPluginId(),
+          '@image' => $destination,
+          '@class' => get_class($t),
+          '@message' => $t->getMessage(),
+        ]);
+        $success = FALSE;
+      }
     }
     // Move temporary local file to remote destination.
     if (isset($permanent_destination) && $success) {
diff --git a/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php b/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php
index e4c44674f9a2ee5c10b034b994cc1c5cf846bb5d..aaa3a9aa3123459dd095635329c9a629aff85e1f 100644
--- a/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php
@@ -452,6 +452,39 @@ public function testCreateNewFailures(): void {
     $this->assertTrue($image->isValid(), 'CreateNew with valid arguments validates the Image.');
   }
 
+  /**
+   * Tests creation of an image that will exceed the memory limit.
+   */
+  public function testInsufficientMemory(): void {
+    // ini_get() may return -1 or null for memory_limit to indicate there is no
+    // limit set. In that case, we need to skip this test.
+    $size = ini_get('memory_limit');
+    if (!$size || (int) $size === -1) {
+      $this->markTestSkipped("There is no memory limit set in the PHP environment.");
+    }
+
+    $image = $this->imageFactory->get('core/tests/fixtures/files/image-test.png');
+
+    $oldGdImage = $image->getToolkit()->getResource();
+    $this->assertFalse($image->createNew(2000000, 2000000));
+    $newGdImage = $image->getToolkit()->getResource();
+
+    // Check that a new resource has not been created, and the old one is still
+    // valid.
+    $this->assertEquals($oldGdImage, $newGdImage);
+  }
+
+  /**
+   * Tests resizing of an image that will exceed the memory available.
+   */
+  public function testInsufficientAvailableMemory(): void {
+    $image = $this->imageFactory->get('core/tests/fixtures/files/image-test.png');
+
+    $memory_in_use = memory_get_usage(TRUE);
+    ini_set('memory_limit', $memory_in_use + 2048);
+    $this->assertFalse($image->resize(200000, 200000));
+  }
+
   /**
    * Tests for GIF images with transparency.
    */