diff --git a/lib/adminlib.php b/lib/adminlib.php
index 0c7b15667da..4b909cf7d67 100644
--- a/lib/adminlib.php
+++ b/lib/adminlib.php
@@ -7968,9 +7968,7 @@ function admin_externalpage_setup($section, $extrabutton = '', array $extraurlpa
  * @return object admin_root object
  */
 function admin_get_root($reload=false, $requirefulltree=true) {
-    global $CFG, $DB, $OUTPUT;
-
-    static $ADMIN = NULL;
+    global $CFG, $DB, $OUTPUT, $ADMIN;
 
     if (is_null($ADMIN)) {
     // create the admin tree!
diff --git a/lib/classes/session/manager.php b/lib/classes/session/manager.php
index f617cc2217c..6568e4b9b22 100644
--- a/lib/classes/session/manager.php
+++ b/lib/classes/session/manager.php
@@ -712,6 +712,7 @@ class manager {
      * @param \stdClass $user record
      */
     public static function set_user(\stdClass $user) {
+        global $ADMIN;
         $GLOBALS['USER'] = $user;
         unset($GLOBALS['USER']->description); // Conserve memory.
         unset($GLOBALS['USER']->password);    // Improve security.
@@ -723,6 +724,9 @@ class manager {
         // Relink session with global $USER just in case it got unlinked somehow.
         $_SESSION['USER'] =& $GLOBALS['USER'];
 
+        // Nullify the $ADMIN tree global. If we're changing users, then this is now stale and must be generated again if needed.
+        $ADMIN = null;
+
         // Init session key.
         sesskey();
     }
diff --git a/lib/tests/admintree_test.php b/lib/tests/admintree_test.php
index 1dae629c0dd..a4a51f298b4 100644
--- a/lib/tests/admintree_test.php
+++ b/lib/tests/admintree_test.php
@@ -414,4 +414,28 @@ class core_admintree_testcase extends advanced_testcase {
         $this->assertEquals('These entries are invalid: nonvalid site name', $adminsetting->write_setting('nonvalid site name'));
         $this->assertEquals('Empty lines are not valid', $adminsetting->write_setting("localhost\n"));
     }
+
+    /**
+     * Verifies the $ADMIN global (adminroot cache) is properly reset when changing users, which might occur naturally during cron.
+     */
+    public function test_adminroot_cache_reset() {
+        $this->resetAfterTest();
+        global $DB;
+        // Current user is a manager at site context, which won't have access to the 'debugging' section of the admin tree.
+        $manageruser = $this->getDataGenerator()->create_user();
+        $context = context_system::instance();
+        $managerrole = $DB->get_record('role', array('shortname' => 'manager'));
+        role_assign($managerrole->id, $manageruser->id, $context->id);
+        $this->setUser($manageruser);
+        $adminroot = admin_get_root();
+        $section = $adminroot->locate('debugging');
+        $this->assertEmpty($section);
+
+        // Now, change the user to an admin user and confirm we get a new copy of the admin tree when next we ask for it.
+        $adminuser = get_admin();
+        $this->setUser($adminuser);
+        $adminroot = admin_get_root();
+        $section = $adminroot->locate('debugging');
+        $this->assertInstanceOf('\admin_settingpage', $section);
+    }
 }