diff --git a/core/modules/user/tests/src/Functional/Update/UserUpdateRoleMigrateTest.php b/core/modules/user/tests/src/Functional/Update/UserUpdateRoleMigrateTest.php
index 0e449bcaccdfd9ae3be17b382a9c06a81190d800..ab7d2c9a2ae28ac5fce9951cb27fe22d2ddc35b6 100644
--- a/core/modules/user/tests/src/Functional/Update/UserUpdateRoleMigrateTest.php
+++ b/core/modules/user/tests/src/Functional/Update/UserUpdateRoleMigrateTest.php
@@ -6,7 +6,7 @@
 use Drupal\user\Entity\Role;
 
 /**
- * Tests user_post_update_update_roles_followup() upgrade path.
+ * Tests user_update_10000() upgrade path.
  *
  * @group Update
  * @group legacy
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index edba7bc50486cde7d757bd48e6950dc1398be91c..ae27e3bbf5ac4048d66e449db258d0ca714f333d 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -5,6 +5,8 @@
  * Install, update and uninstall functions for the user module.
  */
 
+use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
+
 /**
  * Implements hook_schema().
  */
@@ -97,3 +99,40 @@ function user_install() {
 function user_update_last_removed() {
   return 9301;
 }
+
+/**
+ * Remove non-existent permissions created by migrations.
+ */
+function user_update_10000() {
+  $cleaned_roles = [];
+  $existing_permissions = array_keys(\Drupal::service('user.permissions')
+    ->getPermissions());
+  $config_factory = \Drupal::configFactory();
+  $role_ids = $config_factory->listAll('user.role.');
+  foreach ($role_ids as $role_id) {
+    $role_config = $config_factory->getEditable($role_id);
+    $removed_permissions = array_diff($role_config->get('permissions'), $existing_permissions);
+    if (!empty($removed_permissions)) {
+      $cleaned_roles[] = $role_config->get('label');
+      \Drupal::logger('update')->notice(
+        'The role %role has had the following non-existent permission(s) removed: %permissions.',
+        [
+          '%role' => $role_config->get('label'),
+          '%permissions' => implode(', ', $removed_permissions),
+        ]
+      );
+      $permissions = array_intersect($role_config->get('permissions'), $existing_permissions);
+      $role_config->set('permissions', $permissions);
+      $role_config->save();
+    }
+  }
+
+  if (!empty($cleaned_roles)) {
+    return new PluralTranslatableMarkup(
+      count($cleaned_roles),
+      'The role %role_list has had non-existent permissions removed. Check the logs for details.',
+      'The roles %role_list have had non-existent permissions removed. Check the logs for details.',
+      ['%role_list' => implode(', ', $cleaned_roles)]
+    );
+  }
+}
diff --git a/core/modules/user/user.post_update.php b/core/modules/user/user.post_update.php
index 8dd6cf5b474317d2db742d64cb85fd86a2841efe..f1b6da9bc9c16d85c1711001838b1d741f805b1f 100644
--- a/core/modules/user/user.post_update.php
+++ b/core/modules/user/user.post_update.php
@@ -5,10 +5,6 @@
  * Post update functions for User module.
  */
 
-use Drupal\Core\Config\Entity\ConfigEntityUpdater;
-use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
-use Drupal\user\Entity\Role;
-
 /**
  * Implements hook_removed_post_updates().
  */
@@ -18,39 +14,3 @@ function user_removed_post_updates() {
     'user_post_update_update_roles' => '10.0.0',
   ];
 }
-
-/**
- * Remove non-existent permissions created by migrations.
- */
-function user_post_update_update_migrated_roles_followup(&$sandbox = NULL) {
-  $cleaned_roles = [];
-  $existing_permissions = array_keys(\Drupal::service('user.permissions')
-    ->getPermissions());
-  \Drupal::classResolver(ConfigEntityUpdater::class)
-    ->update($sandbox, 'user_role', function (Role $role) use ($existing_permissions, &$cleaned_roles) {
-      $removed_permissions = array_diff($role->getPermissions(), $existing_permissions);
-      if (!empty($removed_permissions)) {
-        $cleaned_roles[] = $role->label();
-        \Drupal::logger('update')->notice(
-          'The role %role has had the following non-existent permission(s) removed: %permissions.',
-          [
-            '%role' => $role->label(),
-            '%permissions' => implode(', ', $removed_permissions),
-          ]
-        );
-        $permissions = array_intersect($role->getPermissions(), $existing_permissions);
-        $role->set('permissions', $permissions);
-        return TRUE;
-      }
-    });
-
-  if (!empty($cleaned_roles)) {
-    return new PluralTranslatableMarkup(
-      count($cleaned_roles),
-      'The role %role_list has had non-existent permissions removed. Check the logs for details.',
-      'The roles %role_list have had non-existent permissions removed. Check the logs for details.',
-      ['%role_list' => implode(', ', $cleaned_roles)]
-    );
-  }
-
-}