diff --git a/core/lib/Drupal/Core/Update/UpdateServiceProvider.php b/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
index 1971ef260a..79dc38544b 100644
--- a/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
+++ b/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
@@ -5,6 +5,7 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\ServiceModifierInterface;
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\DependencyInjection\Reference;
 
@@ -52,6 +53,49 @@ public function alter(ContainerBuilder $container) {
         ->clearTag('path_processor_inbound')
         ->clearTag('path_processor_outbound');
     }
+
+    // Loop over the defined services and remove any with unmet dependencies.
+    // The kernel cannot be booted if the container has such services. This
+    // allows modules to run their update hooks to enable newly added
+    // dependencies.
+    do {
+      $definitions = $container->getDefinitions();
+      foreach ($definitions as $key => $definition) {
+        foreach ($definition->getArguments() as $argument) {
+          if ($argument instanceof Reference) {
+            $argument_id = (string) $argument;
+
+            // Decorated services can be passed the inner service use a
+            // reference that does not exist.
+            if ($definition->getDecoratedService()) {
+              // Construct the inner service ID if the service is decorated.
+              // @see \Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass::process()
+              list(, $renamed_id) = $definition->getDecoratedService();
+              if (!$renamed_id) {
+                $renamed_id = $key . '.inner';
+              }
+              if ($argument_id === $renamed_id) {
+                continue;
+              }
+            }
+
+            if (!$container->has($argument_id) && $argument->getInvalidBehavior() === ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) {
+              // If the container does not have the argument and would throw an
+              // exception, remove the service.
+              $container->removeDefinition($key);
+            }
+          }
+        }
+      }
+      // Remove any aliases which point to undefined services.
+      $aliases = $container->getAliases();
+      foreach ($aliases as $key => $alias) {
+        if (!$container->has((string) $alias)) {
+          $container->removeAlias($key);
+        }
+      }
+      // Repeat if services or aliases have been removed.
+    } while (count($definitions) > count($container->getDefinitions()) || count($aliases) > count($container->getAliases()));
   }
 
 }
diff --git a/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.info.yml b/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.info.yml
new file mode 100644
index 0000000000..eab08261b5
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.info.yml
@@ -0,0 +1,8 @@
+name: 'New Dependency test'
+type: module
+description: 'Support module for update testing.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - new_dependency_test_with_service
diff --git a/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.install b/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.install
new file mode 100644
index 0000000000..326618be5c
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.install
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for the new_dependency_test module.
+ */
+
+/**
+ * Enable the new_dependency_test_with_service module.
+ */
+function new_dependency_test_update_8001() {
+  // Gather the state of the services prior to installing the
+  // new_dependency_test_with_service module.
+  \Drupal::state()->set(
+    'new_dependency_test_update_8001.decorated_service',
+    \Drupal::service('new_dependency_test.another_service')->isDecorated()
+  );
+
+  \Drupal::state()->set(
+    'new_dependency_test_update_8001.decorated_service_custom_inner',
+    \Drupal::service('new_dependency_test.another_service_two')->isDecorated()
+  );
+
+  \Drupal::state()->set(
+    'new_dependency_test_update_8001.has_before_install:new_dependency_test.hard_dependency',
+    \Drupal::hasService('new_dependency_test.hard_dependency')
+  );
+
+  \Drupal::state()->set(
+    'new_dependency_test_update_8001.has_before_install:new_dependency_test.optional_dependency',
+    \Drupal::hasService('new_dependency_test.optional_dependency')
+  );
+
+  // During the update hooks the container is cleaned up to contain only
+  // services that have their dependencies met. Core services are available.
+  \Drupal::getContainer()->get('module_installer')->install(['new_dependency_test_with_service']);
+
+  // Gather the state of the services after installing the
+  // new_dependency_test_with_service module.
+  \Drupal::state()->set(
+    'new_dependency_test_update_8001.has_after_install:new_dependency_test.hard_dependency',
+    \Drupal::hasService('new_dependency_test.hard_dependency')
+  );
+
+  \Drupal::state()->set(
+    'new_dependency_test_update_8001.has_after_install:new_dependency_test.optional_dependency',
+    \Drupal::hasService('new_dependency_test.optional_dependency')
+  );
+}
diff --git a/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.services.yml b/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.services.yml
new file mode 100644
index 0000000000..a0f045e852
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test/new_dependency_test.services.yml
@@ -0,0 +1,25 @@
+services:
+  new_dependency_test.dependent:
+    class: Drupal\new_dependency_test\InjectedService
+    arguments: ['@new_dependency_test_with_service.service']
+  new_dependency_test.hard_dependency:
+    class: Drupal\new_dependency_test\ServiceWithDependency
+    arguments: ['@new_dependency_test.dependent']
+  new_dependency_test.optional_dependency:
+    class: Drupal\new_dependency_test\ServiceWithDependency
+    arguments: ['@?new_dependency_test.dependent']
+  new_dependency_test.alias:
+    alias: new_dependency_test.dependent
+  new_dependency_test.another_service:
+    class: Drupal\new_dependency_test\Service
+  new_dependency_test.another_service.decorated:
+    class: Drupal\new_dependency_test\Service
+    decorates: new_dependency_test.another_service
+    arguments: ['@new_dependency_test.another_service.decorated.inner']
+  new_dependency_test.another_service_two:
+    class: Drupal\new_dependency_test\Service
+  new_dependency_test.another_service_two.decorated:
+    class: Drupal\new_dependency_test\Service
+    decorates: new_dependency_test.another_service_two
+    decoration_inner_name: new_dependency_test.foo
+    arguments: ['@new_dependency_test.foo']
diff --git a/core/modules/system/tests/modules/new_dependency_test/src/InjectedService.php b/core/modules/system/tests/modules/new_dependency_test/src/InjectedService.php
new file mode 100644
index 0000000000..7f0b68bfaf
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test/src/InjectedService.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\new_dependency_test;
+
+use Drupal\new_dependency_test_with_service\NewService;
+
+/**
+ * Generic service with a dependency on a service defined in a new module.
+ */
+class InjectedService {
+
+  /**
+   * The injected service.
+   *
+   * @var \Drupal\new_dependency_test_with_service\NewService
+   */
+  protected $service;
+
+  /**
+   * InjectedService constructor.
+   *
+   * @param \Drupal\new_dependency_test_with_service\NewService $service
+   *   The service of the new module.
+   */
+  public function __construct(NewService $service) {
+    $this->service = $service;
+  }
+
+  /**
+   * Get the simple greeting from the service.
+   *
+   * @return string
+   *   The greeting.
+   */
+  public function greet() {
+    return $this->service->greet();
+  }
+
+}
diff --git a/core/modules/system/tests/modules/new_dependency_test/src/Service.php b/core/modules/system/tests/modules/new_dependency_test/src/Service.php
new file mode 100644
index 0000000000..413226ea4e
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test/src/Service.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\new_dependency_test;
+
+/**
+ * A service that can decorated itself.
+ *
+ * @see new_dependency_test.services.yml
+ */
+class Service {
+
+  /**
+   * The decorated service.
+   *
+   * @var \Drupal\new_dependency_test\Service
+   */
+  protected $inner;
+
+  /**
+   * Service constructor.
+   *
+   * @param \Drupal\new_dependency_test\Service|null $inner
+   *   The service to decorate.
+   */
+  public function __construct(Service $inner = NULL) {
+    $this->inner = $inner;
+  }
+
+  /**
+   * Determines if the service is decorated.
+   *
+   * @return bool
+   *   TRUE if the services is decorated, FALSE if not.
+   */
+  public function isDecorated() {
+    return isset($this->inner);
+  }
+
+}
diff --git a/core/modules/system/tests/modules/new_dependency_test/src/ServiceWithDependency.php b/core/modules/system/tests/modules/new_dependency_test/src/ServiceWithDependency.php
new file mode 100644
index 0000000000..c5c57d500e
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test/src/ServiceWithDependency.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\new_dependency_test;
+
+/**
+ * Service that gets the other service of the same module injected.
+ *
+ * This service indirectly depends on a not-yet-defined service.
+ */
+class ServiceWithDependency {
+
+  /**
+   * The injected service.
+   *
+   * @var \Drupal\new_dependency_test\InjectedService
+   */
+  protected $service;
+
+  /**
+   * ServiceWithDependency constructor.
+   *
+   * @param \Drupal\new_dependency_test\InjectedService|null $service
+   *   The service of the same module which has the new dependency.
+   */
+  public function __construct(InjectedService $service = NULL) {
+    $this->service = $service;
+  }
+
+  /**
+   * Gets a greeting from the injected service and adds to it.
+   *
+   * @return string
+   *   The greeting.
+   */
+  public function greet() {
+    if (isset($this->service)) {
+      return $this->service->greet() . ' World';
+    }
+    return 'Sorry, no service.';
+  }
+
+}
diff --git a/core/modules/system/tests/modules/new_dependency_test_with_service/new_dependency_test_with_service.info.yml b/core/modules/system/tests/modules/new_dependency_test_with_service/new_dependency_test_with_service.info.yml
new file mode 100644
index 0000000000..5091a7f79d
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test_with_service/new_dependency_test_with_service.info.yml
@@ -0,0 +1,6 @@
+name: 'New Dependency test with service'
+type: module
+description: 'Support module for update testing.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/system/tests/modules/new_dependency_test_with_service/new_dependency_test_with_service.services.yml b/core/modules/system/tests/modules/new_dependency_test_with_service/new_dependency_test_with_service.services.yml
new file mode 100644
index 0000000000..26ba284e29
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test_with_service/new_dependency_test_with_service.services.yml
@@ -0,0 +1,3 @@
+services:
+  new_dependency_test_with_service.service:
+    class: Drupal\new_dependency_test_with_service\NewService
diff --git a/core/modules/system/tests/modules/new_dependency_test_with_service/src/NewService.php b/core/modules/system/tests/modules/new_dependency_test_with_service/src/NewService.php
new file mode 100644
index 0000000000..6137fc2ecf
--- /dev/null
+++ b/core/modules/system/tests/modules/new_dependency_test_with_service/src/NewService.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\new_dependency_test_with_service;
+
+/**
+ * Generic service returning a greeting.
+ */
+class NewService {
+
+  /**
+   * Get a simple greeting.
+   *
+   * @return string
+   *   The greeting provided by the new service.
+   */
+  public function greet() {
+    return 'Hello';
+  }
+
+}
diff --git a/core/modules/system/tests/src/Functional/Update/UpdatePathNewDependencyTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePathNewDependencyTest.php
new file mode 100644
index 0000000000..bc52535dbd
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Update/UpdatePathNewDependencyTest.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Drupal\Tests\system\Functional\Update;
+
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
+
+/**
+ * Modules can introduce new dependencies and enable them in update hooks.
+ *
+ * @group system
+ * @group legacy
+ */
+class UpdatePathNewDependencyTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../tests/fixtures/update/drupal-8.6.0.bare.testing.php.gz',
+    ];
+  }
+
+  /**
+   * Test that a module can add services that depend on new modules.
+   */
+  public function testUpdateNewDependency() {
+    // The new_dependency_test before the update is just an empty info.yml file.
+    // The code of the new_dependency_test module is after the update and
+    // contains the dependency on the new_dependency_test_with_service module.
+    $extension_config = $this->container->get('config.factory')->getEditable('core.extension');
+    $extension_config
+      ->set('module.new_dependency_test', 0)
+      ->set('module', module_config_sort($extension_config->get('module')))
+      ->save(TRUE);
+    drupal_set_installed_schema_version('new_dependency_test', \Drupal::CORE_MINIMUM_SCHEMA_VERSION);
+
+    // Rebuild the container and test that the service with the optional unmet
+    // dependency is still available while the ones that fail are not.
+
+    try {
+      $this->rebuildContainer();
+      $this->fail('The container has services with unmet dependencies and should have failed to rebuild.');
+    }
+    catch (ServiceNotFoundException $exception) {
+      $this->assertEquals('The service "new_dependency_test.dependent" has a dependency on a non-existent service "new_dependency_test_with_service.service".', $exception->getMessage());
+    }
+
+    // Running the updates enables the dependency.
+    $this->runUpdates();
+
+    $this->assertTrue(array_key_exists('new_dependency_test', $this->container->get('config.factory')->get('core.extension')->get('module')));
+    $this->assertTrue(array_key_exists('new_dependency_test_with_service', $this->container->get('config.factory')->get('core.extension')->get('module')));
+
+    // Tests that the new services are available and working as expected.
+    $this->assertEquals('Hello', $this->container->get('new_dependency_test_with_service.service')->greet());
+    $this->assertEquals('Hello', $this->container->get('new_dependency_test.dependent')->greet());
+    $this->assertEquals('Hello', $this->container->get('new_dependency_test.alias')->greet());
+    $this->assertEquals('Hello World', $this->container->get('new_dependency_test.hard_dependency')->greet());
+    $this->assertEquals('Hello World', $this->container->get('new_dependency_test.optional_dependency')->greet());
+
+    // Tests that existing decorated services work as expected during update.
+    $this->assertTrue(\Drupal::state()->get('new_dependency_test_update_8001.decorated_service'), 'The new_dependency_test.another_service service is decorated');
+    $this->assertTrue(\Drupal::state()->get('new_dependency_test_update_8001.decorated_service_custom_inner'), 'The new_dependency_test.another_service_two service is decorated');
+
+    // Tests that services are available as expected.
+    $this->assertFalse(\Drupal::state()->get('new_dependency_test_update_8001.has_before_install:new_dependency_test.hard_dependency'), 'The new_dependency_test.hard_dependency is not available prior to install');
+    $this->assertTrue(\Drupal::state()->get('new_dependency_test_update_8001.has_before_install:new_dependency_test.optional_dependency'), 'The new_dependency_test.optional_dependency is available prior to install');
+    $this->assertTrue(\Drupal::state()->get('new_dependency_test_update_8001.has_after_install:new_dependency_test.hard_dependency'), 'The new_dependency_test.hard_dependency is available after install');
+    $this->assertTrue(\Drupal::state()->get('new_dependency_test_update_8001.has_after_install:new_dependency_test.optional_dependency'), 'The new_dependency_test.optional_dependency is available after install');
+  }
+
+}
