diff --git a/app/Auth/UserRepo.php b/app/Auth/UserRepo.php
index d436ab8eb..31b91108d 100644
--- a/app/Auth/UserRepo.php
+++ b/app/Auth/UserRepo.php
@@ -3,6 +3,7 @@
 use Activity;
 use BookStack\Entities\Repos\EntityRepo;
 use BookStack\Exceptions\NotFoundException;
+use BookStack\Exceptions\UserUpdateException;
 use BookStack\Uploads\Image;
 use Exception;
 use Images;
@@ -42,7 +43,7 @@ class UserRepo
      */
     public function getById($id)
     {
-        return $this->user->findOrFail($id);
+        return $this->user->newQuery()->findOrFail($id);
     }
 
     /**
@@ -135,6 +136,40 @@ class UserRepo
         return true;
     }
 
+    /**
+     * Set the assigned user roles via an array of role IDs.
+     * @param User $user
+     * @param array $roles
+     * @throws UserUpdateException
+     */
+    public function setUserRoles(User $user, array $roles)
+    {
+        if ($this->demotingLastAdmin($user, $roles)) {
+            throw new UserUpdateException(trans('errors.role_cannot_remove_only_admin'), $user->getEditUrl());
+        }
+
+        $user->roles()->sync($roles);
+    }
+
+    /**
+     * Check if the given user is the last admin and their new roles no longer
+     * contains the admin role.
+     * @param User $user
+     * @param array $newRoles
+     * @return bool
+     */
+    protected function demotingLastAdmin(User $user, array $newRoles) : bool
+    {
+        if ($this->isOnlyAdmin($user)) {
+            $adminRole = $this->role->getSystemRole('admin');
+            if (!in_array(strval($adminRole->id), $newRoles)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Create a new basic instance of user.
      * @param array $data
@@ -143,7 +178,6 @@ class UserRepo
      */
     public function create(array $data, $verifyEmail = false)
     {
-
         return $this->user->forceCreate([
             'name'     => $data['name'],
             'email'    => $data['email'],
diff --git a/app/Exceptions/NotifyException.php b/app/Exceptions/NotifyException.php
index df96b5d12..78ffde05c 100644
--- a/app/Exceptions/NotifyException.php
+++ b/app/Exceptions/NotifyException.php
@@ -11,7 +11,7 @@ class NotifyException extends \Exception
      * @param string $message
      * @param string    $redirectLocation
      */
-    public function __construct($message, $redirectLocation)
+    public function __construct(string $message, string $redirectLocation = "/")
     {
         $this->message = $message;
         $this->redirectLocation = $redirectLocation;
diff --git a/app/Exceptions/UserUpdateException.php b/app/Exceptions/UserUpdateException.php
new file mode 100644
index 000000000..eb41dece6
--- /dev/null
+++ b/app/Exceptions/UserUpdateException.php
@@ -0,0 +1,3 @@
+<?php namespace BookStack\Exceptions;
+
+class UserUpdateException extends NotifyException {}
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index 24f8b67cb..cc5ada3f2 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -3,6 +3,7 @@
 use BookStack\Auth\Access\SocialAuthService;
 use BookStack\Auth\User;
 use BookStack\Auth\UserRepo;
+use BookStack\Exceptions\UserUpdateException;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 
@@ -15,7 +16,7 @@ class UserController extends Controller
     /**
      * UserController constructor.
      * @param User     $user
-     * @param \BookStack\Auth\UserRepo $userRepo
+     * @param UserRepo $userRepo
      */
     public function __construct(User $user, UserRepo $userRepo)
     {
@@ -59,6 +60,7 @@ class UserController extends Controller
      * Store a newly created user in storage.
      * @param  Request $request
      * @return Response
+     * @throws UserUpdateException
      */
     public function store(Request $request)
     {
@@ -89,7 +91,7 @@ class UserController extends Controller
 
         if ($request->filled('roles')) {
             $roles = $request->get('roles');
-            $user->roles()->sync($roles);
+            $this->userRepo->setUserRoles($user, $roles);
         }
 
         $this->userRepo->downloadAndAssignUserAvatar($user);
@@ -122,8 +124,9 @@ class UserController extends Controller
     /**
      * Update the specified user in storage.
      * @param  Request $request
-     * @param  int     $id
+     * @param  int $id
      * @return Response
+     * @throws UserUpdateException
      */
     public function update(Request $request, $id)
     {
@@ -140,13 +143,13 @@ class UserController extends Controller
             'setting'          => 'array'
         ]);
 
-        $user = $this->user->findOrFail($id);
+        $user = $this->userRepo->getById($id);
         $user->fill($request->all());
 
         // Role updates
         if (userCan('users-manage') && $request->filled('roles')) {
             $roles = $request->get('roles');
-            $user->roles()->sync($roles);
+            $this->userRepo->setUserRoles($user, $roles);
         }
 
         // Password updates
@@ -185,7 +188,7 @@ class UserController extends Controller
             return $this->currentUser->id == $id;
         });
 
-        $user = $this->user->findOrFail($id);
+        $user = $this->userRepo->getById($id);
         $this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name]));
         return view('users/delete', ['user' => $user]);
     }
@@ -194,6 +197,7 @@ class UserController extends Controller
      * Remove the specified user from storage.
      * @param  int $id
      * @return Response
+     * @throws \Exception
      */
     public function destroy($id)
     {
@@ -279,7 +283,7 @@ class UserController extends Controller
             $viewType = 'list';
         }
 
-        $user = $this->user->findOrFail($id);
+        $user = $this->userRepo->getById($id);
         setting()->putUser($user, 'bookshelves_view_type', $viewType);
 
         return redirect()->back(302, [], "/settings/users/$id");
diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php
index 7a881e021..b91a0c3e1 100644
--- a/resources/lang/en/errors.php
+++ b/resources/lang/en/errors.php
@@ -64,6 +64,7 @@ return [
     'role_cannot_be_edited' => 'This role cannot be edited',
     'role_system_cannot_be_deleted' => 'This role is a system role and cannot be deleted',
     'role_registration_default_cannot_delete' => 'This role cannot be deleted while set as the default registration role',
+    'role_cannot_remove_only_admin' => 'This user is the only user assigned to the administrator role. Assign the administrator role to another user before attempting to remove it here.',
 
     // Comments
     'comment_list' => 'An error occurred while fetching the comments.',
diff --git a/tests/Permissions/RolesTest.php b/tests/Permissions/RolesTest.php
index 95cb7cd57..d22946799 100644
--- a/tests/Permissions/RolesTest.php
+++ b/tests/Permissions/RolesTest.php
@@ -78,6 +78,28 @@ class RolesTest extends BrowserKitTest
             ->dontSee($testRoleUpdateName);
     }
 
+    public function test_admin_role_cannot_be_removed_if_last_admin()
+    {
+        $adminRole = Role::where('system_name', '=', 'admin')->first();
+        $adminUser = $this->getAdmin();
+        $adminRole->users()->where('id', '!=', $adminUser->id)->delete();
+        $this->assertEquals($adminRole->users()->count(), 1);
+
+        $viewerRole = $this->getViewer()->roles()->first();
+
+        $editUrl = '/settings/users/' . $adminUser->id;
+        $this->actingAs($adminUser)->put($editUrl, [
+            'name' => $adminUser->name,
+            'email' => $adminUser->email,
+            'roles' => [
+                'viewer' => strval($viewerRole->id),
+            ]
+        ])->followRedirects();
+
+        $this->seePageIs($editUrl);
+        $this->see('This user is the only user assigned to the administrator role');
+    }
+
     public function test_manage_user_permission()
     {
         $this->actingAs($this->user)->visit('/settings/users')