diff --git a/automatic_updates_extensions/automatic_updates_extensions.services.yml b/automatic_updates_extensions/automatic_updates_extensions.services.yml
index a139a889b62aceb910b0e913c63c20869a1adca5..acac491c30d1580bf01acea0732407717f8331ea 100644
--- a/automatic_updates_extensions/automatic_updates_extensions.services.yml
+++ b/automatic_updates_extensions/automatic_updates_extensions.services.yml
@@ -9,3 +9,6 @@ services:
   Drupal\automatic_updates_extensions\Validator\ForbidCoreChangesValidator:
     tags:
       - { name: event_subscriber }
+  Drupal\automatic_updates_extensions\Validator\RequestedUpdateValidator:
+    tags:
+      - { name: event_subscriber }
diff --git a/automatic_updates_extensions/src/Validator/RequestedUpdateValidator.php b/automatic_updates_extensions/src/Validator/RequestedUpdateValidator.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d0a1c0eb7b181dd7d1feb9ee8e0ef49db8f94be
--- /dev/null
+++ b/automatic_updates_extensions/src/Validator/RequestedUpdateValidator.php
@@ -0,0 +1,105 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\automatic_updates_extensions\Validator;
+
+use Composer\Semver\Semver;
+use Drupal\automatic_updates_extensions\ExtensionUpdateStage;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\package_manager\ComposerInspector;
+use Drupal\package_manager\Event\PreApplyEvent;
+use Drupal\package_manager\Event\StatusCheckEvent;
+use Drupal\package_manager\PathLocator;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Validates that requested packages have been updated.
+ *
+ * @internal
+ *   This is an internal part of Automatic Updates and may be changed or removed
+ *   at any time without warning. External code should not interact with this
+ *   class.
+ */
+final class RequestedUpdateValidator implements EventSubscriberInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * Constructs a RequestedUpdateValidator object.
+   *
+   * @param \Drupal\package_manager\ComposerInspector $composerInspector
+   *   The Composer inspector service.
+   * @param \Drupal\package_manager\PathLocator $pathLocator
+   *   The path locator service.
+   */
+  public function __construct(
+    private readonly ComposerInspector $composerInspector,
+    private readonly PathLocator $pathLocator,
+  ) {}
+
+  /**
+   * Validates that requested packages have been updated to the right version.
+   *
+   * @param \Drupal\package_manager\Event\PreApplyEvent|\Drupal\package_manager\Event\StatusCheckEvent $event
+   *   The pre-apply event.
+   */
+  public function checkRequestedStagedVersion(PreApplyEvent|StatusCheckEvent $event): void {
+    $stage = $event->stage;
+    if ($stage->getType() !== 'automatic_updates_extensions:attended' || !$stage->stageDirectoryExists()) {
+      return;
+    }
+    $requested_package_versions = $stage->getPackageVersions();
+    $active = $this->composerInspector->getInstalledPackagesList($this->pathLocator->getProjectRoot());
+    $staged = $this->composerInspector->getInstalledPackagesList($event->stage->getStageDirectory());
+    $changed_stage_packages = $staged->getPackagesWithDifferentVersionsIn($active)->getArrayCopy();
+
+    if (empty($changed_stage_packages)) {
+      $event->addError([$this->t('No updates detected in the staging area.')]);
+      return;
+    }
+
+    // Check for all changed the packages if they are updated to the requested
+    // version.
+    foreach (['production', 'dev'] as $package_type) {
+      foreach ($requested_package_versions[$package_type] as $requested_package_name => $requested_version) {
+        if (array_key_exists($requested_package_name, $changed_stage_packages)) {
+          $staged_version = $changed_stage_packages[$requested_package_name]->version;
+          if (!Semver::satisfies($staged_version, $requested_version)) {
+            $event->addError([
+              $this->t(
+                "The requested update to '@requested_package_name' to version '@requested_version' does not match the actual staged update to '@staged_version'.",
+                [
+                  '@requested_package_name' => $requested_package_name,
+                  '@requested_version' => $requested_version,
+                  '@staged_version' => $staged_version,
+                ]
+              ),
+            ]);
+          }
+        }
+        else {
+          $event->addError([
+            $this->t(
+              "The requested update to '@requested_package_name' to version '@requested_version' was not performed.",
+              [
+                '@requested_package_name' => $requested_package_name,
+                '@requested_version' => $requested_version,
+              ]
+            ),
+          ]);
+        }
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents(): array {
+    $events[StatusCheckEvent::class][] = ['checkRequestedStagedVersion'];
+    $events[PreApplyEvent::class][] = ['checkRequestedStagedVersion'];
+    return $events;
+  }
+
+}
diff --git a/automatic_updates_extensions/tests/src/Functional/StatusCheckerRunAfterUpdateTest.php b/automatic_updates_extensions/tests/src/Functional/StatusCheckerRunAfterUpdateTest.php
index cd782c22e1f53a147357f378248bb990ba80133d..35c6d023f3adb159fe383e1d8941912f99ab4d6d 100644
--- a/automatic_updates_extensions/tests/src/Functional/StatusCheckerRunAfterUpdateTest.php
+++ b/automatic_updates_extensions/tests/src/Functional/StatusCheckerRunAfterUpdateTest.php
@@ -48,6 +48,7 @@ class StatusCheckerRunAfterUpdateTest extends UpdaterFormTestBase {
     $assert_session->pageTextNotContains(static::$warningsExplanation);
 
     $this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1');
+    $this->getStageFixtureManipulator()->setVersion('drupal/semver_test', '8.1.1');
     $this->assertUpdatesCount(1);
     $page->checkField('projects[semver_test]');
     $page->pressButton('Update');
diff --git a/automatic_updates_extensions/tests/src/Functional/SuccessfulUpdateTest.php b/automatic_updates_extensions/tests/src/Functional/SuccessfulUpdateTest.php
index fe0b85e685b49c070d7406ba32639956332b7f61..5b2e3f5a27889d79bc407e635f06f3f72f62bf5a 100644
--- a/automatic_updates_extensions/tests/src/Functional/SuccessfulUpdateTest.php
+++ b/automatic_updates_extensions/tests/src/Functional/SuccessfulUpdateTest.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace Drupal\Tests\automatic_updates_extensions\Functional;
 
 use Drupal\package_manager\Event\PreApplyEvent;
+use Drupal\package_manager\LegacyVersionUtility;
 use Drupal\package_manager_test_validation\StagedDatabaseUpdateValidator;
 
 /**
@@ -60,6 +61,7 @@ class SuccessfulUpdateTest extends UpdaterFormTestBase {
     $path_to_fixtures_folder = $project_name === 'aaa_update_test' ? '/../../../../package_manager/tests' : '/../..';
     $this->setReleaseMetadata(__DIR__ . $path_to_fixtures_folder . '/fixtures/release-history/' . $project_name . '.1.1.xml');
     $this->setProjectInstalledVersion([$project_name => $installed_version]);
+    $this->getStageFixtureManipulator()->setVersion('drupal/' . $project_name, LegacyVersionUtility::convertToSemanticVersion($target_version));
     $this->checkForUpdates();
     $state = $this->container->get('state');
     $state->set('system.maintenance_mode', $maintenance_mode_on);
diff --git a/automatic_updates_extensions/tests/src/Functional/UnsuccessfulUpdateTest.php b/automatic_updates_extensions/tests/src/Functional/UnsuccessfulUpdateTest.php
index 3da2f77655797347d2c3e8b6b6fd49bca57be88b..673c9561fc3fce1bd2b7099e81684289a296d003 100644
--- a/automatic_updates_extensions/tests/src/Functional/UnsuccessfulUpdateTest.php
+++ b/automatic_updates_extensions/tests/src/Functional/UnsuccessfulUpdateTest.php
@@ -31,6 +31,7 @@ class UnsuccessfulUpdateTest extends UpdaterFormTestBase {
     $this->drupalGet('/admin/reports/updates');
     $this->clickLink('Update Extensions');
     $this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1');
+    $this->getStageFixtureManipulator()->setVersion('drupal/semver_test', '8.1.1');
     $this->assertUpdatesCount(1);
     $this->checkForMetaRefresh();
     $assert->pageTextNotContains(static::$errorsExplanation);
diff --git a/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php b/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php
index b90894280731c2773cf5dc60f9c703732cb6465b..8acb822a15822d55337bd2a9beab9739cfc90f7a 100644
--- a/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php
+++ b/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php
@@ -32,6 +32,7 @@ class UpdateErrorTest extends UpdaterFormTestBase {
     $assert_session->pageTextNotContains(static::$warningsExplanation);
 
     $this->assertTableShowsUpdates('Semver Test', '8.1.0', '8.1.1');
+    $this->getStageFixtureManipulator()->setVersion('drupal/semver_test', '8.1.1');
     $this->assertUpdatesCount(1);
     $page->checkField('projects[semver_test]');
     $page->pressButton('Update');
diff --git a/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php b/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php
index 597b6e9b66809d908b1638f11428eda7ae0d3f3d..1e022e6aa92de100cb320d7bfbb22aa2b60b46fd 100644
--- a/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php
+++ b/automatic_updates_extensions/tests/src/Kernel/AutomaticUpdatesExtensionsKernelTestBase.php
@@ -56,7 +56,7 @@ abstract class AutomaticUpdatesExtensionsKernelTestBase extends AutomaticUpdates
       ], TRUE)
       ->addPackage([
         "name" => "drupal/semver_test",
-        "version" => "1.0.0",
+        "version" => "8.1.0",
         "type" => "drupal-module",
       ])
       ->addPackage([
diff --git a/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdateStageTest.php b/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdateStageTest.php
index 76e8e06daf83e86ae8a5be9fe38f15f031748b3b..505abe68589c360f42457c6260ee5347e6b51dd9 100644
--- a/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdateStageTest.php
+++ b/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdateStageTest.php
@@ -100,6 +100,7 @@ class ExtensionUpdateStageTest extends AutomaticUpdatesExtensionsKernelTestBase
       [
         'update',
         '--with-all-dependencies',
+        '--optimize-autoloader',
         'drupal/my_module:9.8.1',
         'drupal/my_dev_module:1.2.0-alpha1@alpha',
       ],
diff --git a/automatic_updates_extensions/tests/src/Kernel/Validator/RequestedUpdateValidatorTest.php b/automatic_updates_extensions/tests/src/Kernel/Validator/RequestedUpdateValidatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e2d33ae6caaf1437e586e46539e9f3b8198a1b3
--- /dev/null
+++ b/automatic_updates_extensions/tests/src/Kernel/Validator/RequestedUpdateValidatorTest.php
@@ -0,0 +1,114 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\automatic_updates_extensions\Kernel\Validator;
+
+use Drupal\automatic_updates_extensions\ExtensionUpdateStage;
+use Drupal\fixture_manipulator\ActiveFixtureManipulator;
+use Drupal\package_manager\Exception\StageEventException;
+use Drupal\package_manager\ValidationResult;
+use Drupal\Tests\automatic_updates_extensions\Kernel\AutomaticUpdatesExtensionsKernelTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\automatic_updates_extensions\Validator\RequestedUpdateValidator
+ * @group automatic_updates_extensions
+ * @internal
+ */
+class RequestedUpdateValidatorTest extends AutomaticUpdatesExtensionsKernelTestBase {
+
+  /**
+   * Tests error messages if requested updates were not staged.
+   *
+   * @param array $staged_versions
+   *   An array of the staged versions where the keys are the package names and
+   *   the values are the package versions.
+   * @param array $expected_results
+   *   The expected validation results.
+   *
+   * @dataProvider providerTestErrorMessage
+   */
+  public function testErrorMessage(array $staged_versions, array $expected_results): void {
+    if ($staged_versions) {
+      // If we are going to stage updates to Drupal packages also update a
+      // non-Drupal. The validator should ignore the non-Drupal packages.
+      (new ActiveFixtureManipulator())
+        ->addPackage([
+          "name" => 'vendor/non-drupal-package',
+          "version" => "1.0.0",
+          "type" => "drupal-module",
+        ])
+        ->commitChanges();
+      $this->getStageFixtureManipulator()->setVersion('vendor/non-drupal-package', '1.0.1');
+      foreach ($staged_versions as $package => $version) {
+        $this->getStageFixtureManipulator()->setVersion($package, $version);
+      }
+    }
+
+    $this->setReleaseMetadata([
+      'semver_test' => __DIR__ . '/../../../fixtures/release-history/semver_test.1.1.xml',
+      'drupal' => __DIR__ . '/../../../../../package_manager/tests/fixtures/release-history/drupal.9.8.2.xml',
+      'aaa_update_test' => __DIR__ . "/../../../../../package_manager/tests/fixtures/release-history/aaa_update_test.1.1.xml",
+    ]);
+    // Set the project version to '8.0.1' so that there 2 versions of above this
+    // that will be in the list of supported releases, 8.1.0 and 8.1.1.
+    (new ActiveFixtureManipulator())
+      ->setVersion('drupal/semver_test', '8.0.1')
+      ->commitChanges();
+    // @todo Replace with use of the trait from the Update module in https://drupal.org/i/3348234.
+    $module_info = ['version' => '8.0.1', 'project' => 'semver_test'];
+    $this->config('update_test.settings')
+      ->set("system_info.semver_test", $module_info)
+      ->save();
+
+    $stage = $this->container->get(ExtensionUpdateStage::class);
+    $stage->begin([
+      'semver_test' => '8.1.1',
+      'aaa_update_test' => '8.x-1.1',
+    ]);
+    $stage->stage();
+    $this->assertStatusCheckResults($expected_results, $stage);
+    try {
+      $stage->apply();
+      $this->fail('Expecting an exception.');
+    }
+    catch (StageEventException $exception) {
+      $this->assertExpectedResultsFromException($expected_results, $exception);
+    }
+  }
+
+  /**
+   * Data provider for testErrorMessage().
+   *
+   * @return mixed[]
+   *   The test cases.
+   */
+  public function providerTestErrorMessage() {
+    return [
+      'no updates' => [
+        [],
+        [
+          ValidationResult::createError([t('No updates detected in the staging area.')]),
+        ],
+      ],
+      '1 project not updated' => [
+        [
+          'drupal/aaa_update_test' => '1.1.0',
+        ],
+        [
+          ValidationResult::createError([t("The requested update to 'drupal/semver_test' to version '8.1.1' was not performed.")]),
+        ],
+      ],
+      'project updated to wrong version' => [
+        [
+          'drupal/semver_test' => '8.1.0',
+          'drupal/aaa_update_test' => '1.1.0',
+        ],
+        [
+          ValidationResult::createError([t("The requested update to 'drupal/semver_test' to version '8.1.1' does not match the actual staged update to '8.1.0'.")]),
+        ],
+      ],
+    ];
+  }
+
+}
diff --git a/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php b/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php
index 4ff92ffd7c6f1d6a9543f8fda25e4a7dc0439bdd..c5ad35509855db93291903697664d3f78343fb1a 100644
--- a/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php
+++ b/automatic_updates_extensions/tests/src/Kernel/Validator/UpdateReleaseValidatorTest.php
@@ -79,6 +79,9 @@ class UpdateReleaseValidatorTest extends AutomaticUpdatesExtensionsKernelTestBas
       ];
     }
     else {
+      // Ensure the correct version of the package is staged because the update
+      // is expected to succeed.
+      $this->getStageFixtureManipulator()->setVersion("drupal/$project", LegacyVersionUtility::convertToSemanticVersion($target_version));
       $expected_results = [];
     }
 
diff --git a/package_manager/src/StageBase.php b/package_manager/src/StageBase.php
index c51efdfef6c8880070f827eddcc4f97fc02ac771..4416133dd19615e7f1d05318d24336b8b8a8ceed 100644
--- a/package_manager/src/StageBase.php
+++ b/package_manager/src/StageBase.php
@@ -456,7 +456,7 @@ abstract class StageBase implements LoggerAwareInterface {
 
     // If constraints were changed, update those packages.
     if ($runtime || $dev) {
-      $command = array_merge(['update', '--with-all-dependencies'], $runtime, $dev);
+      $command = array_merge(['update', '--with-all-dependencies', '--optimize-autoloader'], $runtime, $dev);
       $do_stage($command);
     }
     $this->dispatch(new PostRequireEvent($this, $runtime, $dev));
diff --git a/tests/src/Kernel/UpdateStageTest.php b/tests/src/Kernel/UpdateStageTest.php
index 0169b8d2e916541ea931e3b94f1e589516fc1ae8..bc1d323a65549765e1d44f4bef8d6f9e21f9b474 100644
--- a/tests/src/Kernel/UpdateStageTest.php
+++ b/tests/src/Kernel/UpdateStageTest.php
@@ -102,6 +102,7 @@ class UpdateStageTest extends AutomaticUpdatesKernelTestBase {
       [
         'update',
         '--with-all-dependencies',
+        '--optimize-autoloader',
         'drupal/core-recommended:9.8.1',
         'drupal/core-dev:9.8.1',
       ],