diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 8d43a857dd..9c37652360 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -416,6 +416,7 @@ public function invokeAll($hook, array $args = []) {
    * {@inheritdoc}
    */
   public function invokeDeprecated($description, $module, $hook, array $args = []) {
+    @trigger_error(sprintf('%s::invokeDeprecated() has been deprecated since Drupal 8.7. Declare hook_%s() deprecated by implementing hook_hook_info() instead.', ModuleHandlerInterface::class, $hook), E_USER_DEPRECATED);
     $result = $this->invoke($module, $hook, $args);
     $this->triggerDeprecationError($description, $hook);
     return $result;
@@ -425,6 +426,7 @@ public function invokeDeprecated($description, $module, $hook, array $args = [])
    * {@inheritdoc}
    */
   public function invokeAllDeprecated($description, $hook, array $args = []) {
+    @trigger_error(sprintf('%s::invokeAllDeprecated() has been deprecated since Drupal 8.7. Declare hook_%s() deprecated by implementing hook_hook_info() instead.', ModuleHandlerInterface::class, $hook), E_USER_DEPRECATED);
     $result = $this->invokeAll($hook, $args);
     $this->triggerDeprecationError($description, $hook);
     return $result;
@@ -544,6 +546,7 @@ public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
    * {@inheritdoc}
    */
   public function alterDeprecated($description, $type, &$data, &$context1 = NULL, &$context2 = NULL) {
+    @trigger_error(sprintf('%s::alterDeprecated() has been deprecated since Drupal 8.7. Declare hook_%s() deprecated by implementing hook_hook_info() instead.', ModuleHandlerInterface::class, $hook), E_USER_DEPRECATED);
     // Invoke the alter hook. This has the side effect of populating
     // $this->alterFunctions.
     $this->alter($type, $data, $context1, $context2);
@@ -652,6 +655,9 @@ protected function buildImplementationInfo($hook) {
         }
       }
     }
+    if (isset($hook_info['deprecated'])) {
+      @trigger_error(sprintf('hook_%s() is deprecated: %s. However, the following modules still implement it: %s', $hook, $hook_info['deprecated'], implode(', ', array_keys($implementations))), E_USER_DEPRECATED);
+    }
     return $implementations;
   }
 
diff --git a/core/modules/hal/hal.module b/core/modules/hal/hal.module
index 0833e47758..0d10110d23 100644
--- a/core/modules/hal/hal.module
+++ b/core/modules/hal/hal.module
@@ -7,6 +7,20 @@
 
 use Drupal\Core\Routing\RouteMatchInterface;
 
+/**
+ * Implements hook_hook_info().
+ */
+function hal_hook_info() {
+  return [
+    'rest_relation_uri' => [
+      'deprecated' => 'This hook is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Implement hook_hal_relation_uri_alter() instead.',
+    ],
+    'rest_type_uri' => [
+      'deprecated' => 'This hook is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Implement hook_hal_type_uri_alter() instead.',
+    ],
+  ];
+}
+
 /**
  * Implements hook_help().
  */
diff --git a/core/modules/hal/src/LinkManager/RelationLinkManager.php b/core/modules/hal/src/LinkManager/RelationLinkManager.php
index cf858c7008..502193c695 100644
--- a/core/modules/hal/src/LinkManager/RelationLinkManager.php
+++ b/core/modules/hal/src/LinkManager/RelationLinkManager.php
@@ -70,7 +70,7 @@ public function getRelationUri($entity_type, $bundle, $field_name, $context = []
     // override the RelationLinkManager class/service to return the desired URL.
     $uri = $this->getLinkDomain($context) . "/rest/relation/$entity_type/$bundle/$field_name";
     $this->moduleHandler->alter('hal_relation_uri', $uri, $context);
-    $this->moduleHandler->alterDeprecated('This hook is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Implement hook_hal_relation_uri_alter() instead.', 'rest_relation_uri', $uri, $context);
+    $this->moduleHandler->alter('rest_relation_uri', $uri, $context);
     return $uri;
   }
 
diff --git a/core/modules/hal/src/LinkManager/TypeLinkManager.php b/core/modules/hal/src/LinkManager/TypeLinkManager.php
index 62be23d2bc..4191242551 100644
--- a/core/modules/hal/src/LinkManager/TypeLinkManager.php
+++ b/core/modules/hal/src/LinkManager/TypeLinkManager.php
@@ -71,7 +71,7 @@ public function getTypeUri($entity_type, $bundle, $context = []) {
     // TypeLinkManager class/service to return the desired URL.
     $uri = $this->getLinkDomain($context) . "/rest/type/$entity_type/$bundle";
     $this->moduleHandler->alter('hal_type_uri', $uri, $context);
-    $this->moduleHandler->alterDeprecated('This hook is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Implement hook_hal_type_uri_alter() instead.', 'rest_type_uri', $uri, $context);
+    $this->moduleHandler->alter('rest_type_uri', $uri, $context);
     return $uri;
   }
 
diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleHandlerDeprecatedHookUnimplementedTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleHandlerDeprecatedHookUnimplementedTest.php
index 1d4e833e82..c2c91355b1 100644
--- a/core/tests/Drupal/KernelTests/Core/Extension/ModuleHandlerDeprecatedHookUnimplementedTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleHandlerDeprecatedHookUnimplementedTest.php
@@ -2,17 +2,22 @@
 
 namespace Drupal\KernelTests\Core\Extension;
 
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\KernelTests\KernelTestBase;
+use Drupal\Tests\Traits\ExpectDeprecationTrait;
 
 /**
  * Test whether unimplemented deprecated hook invocations trigger errors.
  *
  * @group Extension
+ * @group legacy
  *
  * @coversDefaultClass Drupal\Core\Extension\ModuleHandler
  */
 class ModuleHandlerDeprecatedHookUnimplementedTest extends KernelTestBase {
 
+  use ExpectDeprecationTrait;
+
   /**
    * @covers ::alterDeprecated
    * @covers ::invokeAllDeprecated
@@ -21,6 +26,12 @@ class ModuleHandlerDeprecatedHookUnimplementedTest extends KernelTestBase {
   public function testUnimplementedHooks() {
     $unimplemented_hook_name = 'unimplemented_hook_name';
 
+    $this->expectedDeprecations([
+      sprintf('%s::invokeDeprecated() has been deprecated since Drupal 8.7. Declare hook_%s() deprecated by implementing hook_hook_info() instead.', ModuleHandlerInterface::class, $unimplemented_hook_name),
+      sprintf('%s::invokeAllDeprecated() has been deprecated since Drupal 8.7. Declare hook_%s() deprecated by implementing hook_hook_info() instead.', ModuleHandlerInterface::class, $unimplemented_hook_name),
+      sprintf('%s::alterDeprecated() has been deprecated since Drupal 8.7. Declare hook_%s() deprecated by implementing hook_hook_info() instead.', ModuleHandlerInterface::class, $unimplemented_hook_name),
+    ]);
+
     /* @var $module_handler \Drupal\Core\Extension\ModuleHandlerInterface */
     $module_handler = $this->container->get('module_handler');
 
