diff --git a/django/core/checks/urls.py b/django/core/checks/urls.py
index 34eff9671d..aef2bfebb0 100644
--- a/django/core/checks/urls.py
+++ b/django/core/checks/urls.py
@@ -1,6 +1,8 @@
+import inspect
 from collections import Counter
 
 from django.conf import settings
+from django.core.exceptions import ViewDoesNotExist
 
 from . import Error, Tags, Warning, register
 
@@ -115,3 +117,43 @@ def E006(name):
         "The {} setting must end with a slash.".format(name),
         id="urls.E006",
     )
+
+
+@register(Tags.urls)
+def check_custom_error_handlers(app_configs, **kwargs):
+    if not getattr(settings, "ROOT_URLCONF", None):
+        return []
+
+    from django.urls import get_resolver
+
+    resolver = get_resolver()
+
+    errors = []
+    # All handlers take (request, exception) arguments except handler500
+    # which takes (request).
+    for status_code, num_parameters in [(400, 2), (403, 2), (404, 2), (500, 1)]:
+        try:
+            handler = resolver.resolve_error_handler(status_code)
+        except (ImportError, ViewDoesNotExist) as e:
+            path = getattr(resolver.urlconf_module, "handler%s" % status_code)
+            msg = (
+                "The custom handler{status_code} view '{path}' could not be "
+                "imported."
+            ).format(status_code=status_code, path=path)
+            errors.append(Error(msg, hint=str(e), id="urls.E008"))
+            continue
+        signature = inspect.signature(handler)
+        args = [None] * num_parameters
+        try:
+            signature.bind(*args)
+        except TypeError:
+            msg = (
+                "The custom handler{status_code} view '{path}' does not "
+                "take the correct number of arguments ({args})."
+            ).format(
+                status_code=status_code,
+                path=handler.__module__ + "." + handler.__qualname__,
+                args="request, exception" if num_parameters == 2 else "request",
+            )
+            errors.append(Error(msg, id="urls.E007"))
+    return errors
diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py
index 3607c84228..5f9941dd65 100644
--- a/django/urls/resolvers.py
+++ b/django/urls/resolvers.py
@@ -19,7 +19,7 @@ from asgiref.local import Local
 from django.conf import settings
 from django.core.checks import Error, Warning
 from django.core.checks.urls import check_resolver
-from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
+from django.core.exceptions import ImproperlyConfigured
 from django.utils.datastructures import MultiValueDict
 from django.utils.functional import cached_property
 from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes
@@ -518,40 +518,8 @@ class URLResolver:
         messages = []
         for pattern in self.url_patterns:
             messages.extend(check_resolver(pattern))
-        messages.extend(self._check_custom_error_handlers())
         return messages or self.pattern.check()
 
-    def _check_custom_error_handlers(self):
-        messages = []
-        # All handlers take (request, exception) arguments except handler500
-        # which takes (request).
-        for status_code, num_parameters in [(400, 2), (403, 2), (404, 2), (500, 1)]:
-            try:
-                handler = self.resolve_error_handler(status_code)
-            except (ImportError, ViewDoesNotExist) as e:
-                path = getattr(self.urlconf_module, "handler%s" % status_code)
-                msg = (
-                    "The custom handler{status_code} view '{path}' could not be "
-                    "imported."
-                ).format(status_code=status_code, path=path)
-                messages.append(Error(msg, hint=str(e), id="urls.E008"))
-                continue
-            signature = inspect.signature(handler)
-            args = [None] * num_parameters
-            try:
-                signature.bind(*args)
-            except TypeError:
-                msg = (
-                    "The custom handler{status_code} view '{path}' does not "
-                    "take the correct number of arguments ({args})."
-                ).format(
-                    status_code=status_code,
-                    path=handler.__module__ + "." + handler.__qualname__,
-                    args="request, exception" if num_parameters == 2 else "request",
-                )
-                messages.append(Error(msg, id="urls.E007"))
-        return messages
-
     def _populate(self):
         # Short-circuit if called recursively in this thread to prevent
         # infinite recursion. Concurrent threads may call this at the same
diff --git a/tests/check_framework/test_urls.py b/tests/check_framework/test_urls.py
index 4b6a4a6f3e..a31c5fd856 100644
--- a/tests/check_framework/test_urls.py
+++ b/tests/check_framework/test_urls.py
@@ -2,6 +2,7 @@ from django.conf import settings
 from django.core.checks.messages import Error, Warning
 from django.core.checks.urls import (
     E006,
+    check_custom_error_handlers,
     check_url_config,
     check_url_namespaces_unique,
     check_url_settings,
@@ -243,7 +244,7 @@ class CheckCustomErrorHandlersTests(SimpleTestCase):
         ROOT_URLCONF="check_framework.urls.bad_function_based_error_handlers",
     )
     def test_bad_function_based_handlers(self):
-        result = check_url_config(None)
+        result = check_custom_error_handlers(None)
         self.assertEqual(len(result), 4)
         for code, num_params, error in zip([400, 403, 404, 500], [2, 2, 2, 1], result):
             with self.subTest("handler{}".format(code)):
@@ -264,7 +265,7 @@ class CheckCustomErrorHandlersTests(SimpleTestCase):
         ROOT_URLCONF="check_framework.urls.bad_class_based_error_handlers",
     )
     def test_bad_class_based_handlers(self):
-        result = check_url_config(None)
+        result = check_custom_error_handlers(None)
         self.assertEqual(len(result), 4)
         for code, num_params, error in zip([400, 403, 404, 500], [2, 2, 2, 1], result):
             with self.subTest("handler%s" % code):
@@ -287,7 +288,7 @@ class CheckCustomErrorHandlersTests(SimpleTestCase):
         ROOT_URLCONF="check_framework.urls.bad_error_handlers_invalid_path"
     )
     def test_bad_handlers_invalid_path(self):
-        result = check_url_config(None)
+        result = check_custom_error_handlers(None)
         paths = [
             "django.views.bad_handler",
             "django.invalid_module.bad_handler",
@@ -318,14 +319,14 @@ class CheckCustomErrorHandlersTests(SimpleTestCase):
         ROOT_URLCONF="check_framework.urls.good_function_based_error_handlers",
     )
     def test_good_function_based_handlers(self):
-        result = check_url_config(None)
+        result = check_custom_error_handlers(None)
         self.assertEqual(result, [])
 
     @override_settings(
         ROOT_URLCONF="check_framework.urls.good_class_based_error_handlers",
     )
     def test_good_class_based_handlers(self):
-        result = check_url_config(None)
+        result = check_custom_error_handlers(None)
         self.assertEqual(result, [])