diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs
index 3a791215..d4529a40 100644
--- a/src/api/client_server/account.rs
+++ b/src/api/client_server/account.rs
@@ -149,18 +149,17 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
                 return Err(Error::Uiaa(uiaainfo));
             }
         // Success!
+        } else if let Some(json) = body.json_body {
+            uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
+            services().uiaa.create(
+                &UserId::parse_with_server_name("", services().globals.server_name())
+                    .expect("we know this is valid"),
+                "".into(),
+                &uiaainfo,
+                &json,
+            )?;
+            return Err(Error::Uiaa(uiaainfo));
         } else {
-            if let Some(json) = body.json_body {
-                uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
-                services().uiaa.create(
-                    &UserId::parse_with_server_name("", services().globals.server_name())
-                        .expect("we know this is valid"),
-                    "".into(),
-                    &uiaainfo,
-                    &json,
-                )?;
-                return Err(Error::Uiaa(uiaainfo));
-            }
             return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
         }
     }
@@ -240,19 +239,22 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
 
     // If this is the first real user, grant them admin privileges
     // Note: the server user, @conduit:servername, is generated first
-    if !is_guest
-        && services()
-            .rooms
-            .state_cache
-            .room_joined_count(&services().admin.get_admin_room())?
-            == Some(1)
-    {
-        services()
-            .admin
-            .make_user_admin(&user_id, displayname)
-            .await?;
+    if !is_guest {
+        if let Some(admin_room) = services().admin.get_admin_room()? {
+            if services()
+                .rooms
+                .state_cache
+                .room_joined_count(&admin_room)?
+                == Some(1)
+            {
+                services()
+                    .admin
+                    .make_user_admin(&user_id, displayname)
+                    .await?;
 
-        warn!("Granting {} admin privileges as the first user", user_id);
+                warn!("Granting {} admin privileges as the first user", user_id);
+            }
+        }
     }
 
     Ok(register::v3::Response {
diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs
index b3c18d18..44c7934a 100644
--- a/src/service/admin/mod.rs
+++ b/src/service/admin/mod.rs
@@ -214,50 +214,51 @@ impl Service {
         let conduit_user = UserId::parse(format!("@conduit:{}", services().globals.server_name()))
             .expect("@conduit:server_name is valid");
 
-        let conduit_room = services().admin.get_admin_room();
+        if let Ok(Some(conduit_room)) = services().admin.get_admin_room() {
+            let send_message = |message: RoomMessageEventContent,
+                                mutex_lock: &MutexGuard<'_, ()>| {
+                services()
+                    .rooms
+                    .timeline
+                    .build_and_append_pdu(
+                        PduBuilder {
+                            event_type: TimelineEventType::RoomMessage,
+                            content: to_raw_value(&message)
+                                .expect("event is valid, we just created it"),
+                            unsigned: None,
+                            state_key: None,
+                            redacts: None,
+                        },
+                        &conduit_user,
+                        &conduit_room,
+                        mutex_lock,
+                    )
+                    .unwrap();
+            };
 
-        let send_message = |message: RoomMessageEventContent, mutex_lock: &MutexGuard<'_, ()>| {
-            services()
-                .rooms
-                .timeline
-                .build_and_append_pdu(
-                    PduBuilder {
-                        event_type: TimelineEventType::RoomMessage,
-                        content: to_raw_value(&message)
-                            .expect("event is valid, we just created it"),
-                        unsigned: None,
-                        state_key: None,
-                        redacts: None,
-                    },
-                    &conduit_user,
-                    &conduit_room,
-                    mutex_lock,
-                )
-                .unwrap();
-        };
+            loop {
+                tokio::select! {
+                    Some(event) = receiver.recv() => {
+                        let message_content = match event {
+                            AdminRoomEvent::SendMessage(content) => content,
+                            AdminRoomEvent::ProcessMessage(room_message) => self.process_admin_message(room_message).await
+                        };
 
-        loop {
-            tokio::select! {
-                Some(event) = receiver.recv() => {
-                    let message_content = match event {
-                        AdminRoomEvent::SendMessage(content) => content,
-                        AdminRoomEvent::ProcessMessage(room_message) => self.process_admin_message(room_message).await
-                    };
+                        let mutex_state = Arc::clone(
+                            services().globals
+                                .roomid_mutex_state
+                                .write()
+                                .unwrap()
+                                .entry(conduit_room.to_owned())
+                                .or_default(),
+                        );
 
-                    let mutex_state = Arc::clone(
-                        services().globals
-                            .roomid_mutex_state
-                            .write()
-                            .unwrap()
-                            .entry(conduit_room.to_owned())
-                            .or_default(),
-                    );
+                        let state_lock = mutex_state.lock().await;
 
-                    let state_lock = mutex_state.lock().await;
+                        send_message(message_content, &state_lock);
 
-                    send_message(message_content, &state_lock);
-
-                    drop(state_lock);
+                        drop(state_lock);
+                    }
                 }
             }
         }
@@ -1097,9 +1098,8 @@ impl Service {
 
     /// Gets the room ID of the admin room
     ///
-    /// If the room does not exist, this function panics, since it should have been created on first run
-    // ^ was the case before this function when the following code was re-used in multiple places
-    pub(crate) fn get_admin_room(&self) -> OwnedRoomId {
+    /// Errors are propagated from the database, and will have None if there is no admin room
+    pub(crate) fn get_admin_room(&self) -> Result<Option<OwnedRoomId>> {
         let admin_room_alias: Box<RoomAliasId> =
             format!("#admins:{}", services().globals.server_name())
                 .try_into()
@@ -1109,8 +1109,6 @@ impl Service {
             .rooms
             .alias
             .resolve_local_alias(&admin_room_alias)
-            .expect("Room ID should be valid unicode, since this server created it")
-            .expect("Admin room must exist")
     }
 
     /// Invite the user to the conduit admin room.
@@ -1121,94 +1119,93 @@ impl Service {
         user_id: &UserId,
         displayname: String,
     ) -> Result<()> {
-        let room_id = services().admin.get_admin_room();
+        if let Some(room_id) = services().admin.get_admin_room()? {
+            let mutex_state = Arc::clone(
+                services()
+                    .globals
+                    .roomid_mutex_state
+                    .write()
+                    .unwrap()
+                    .entry(room_id.clone())
+                    .or_default(),
+            );
+            let state_lock = mutex_state.lock().await;
 
-        let mutex_state = Arc::clone(
-            services()
-                .globals
-                .roomid_mutex_state
-                .write()
-                .unwrap()
-                .entry(room_id.clone())
-                .or_default(),
-        );
-        let state_lock = mutex_state.lock().await;
+            // Use the server user to grant the new admin's power level
+            let conduit_user =
+                UserId::parse_with_server_name("conduit", services().globals.server_name())
+                    .expect("@conduit:server_name is valid");
 
-        // Use the server user to grant the new admin's power level
-        let conduit_user =
-            UserId::parse_with_server_name("conduit", services().globals.server_name())
-                .expect("@conduit:server_name is valid");
+            // Invite and join the real user
+            services().rooms.timeline.build_and_append_pdu(
+                PduBuilder {
+                    event_type: TimelineEventType::RoomMember,
+                    content: to_raw_value(&RoomMemberEventContent {
+                        membership: MembershipState::Invite,
+                        displayname: None,
+                        avatar_url: None,
+                        is_direct: None,
+                        third_party_invite: None,
+                        blurhash: None,
+                        reason: None,
+                        join_authorized_via_users_server: None,
+                    })
+                    .expect("event is valid, we just created it"),
+                    unsigned: None,
+                    state_key: Some(user_id.to_string()),
+                    redacts: None,
+                },
+                &conduit_user,
+                &room_id,
+                &state_lock,
+            )?;
+            services().rooms.timeline.build_and_append_pdu(
+                PduBuilder {
+                    event_type: TimelineEventType::RoomMember,
+                    content: to_raw_value(&RoomMemberEventContent {
+                        membership: MembershipState::Join,
+                        displayname: Some(displayname),
+                        avatar_url: None,
+                        is_direct: None,
+                        third_party_invite: None,
+                        blurhash: None,
+                        reason: None,
+                        join_authorized_via_users_server: None,
+                    })
+                    .expect("event is valid, we just created it"),
+                    unsigned: None,
+                    state_key: Some(user_id.to_string()),
+                    redacts: None,
+                },
+                user_id,
+                &room_id,
+                &state_lock,
+            )?;
 
-        // Invite and join the real user
-        services().rooms.timeline.build_and_append_pdu(
-            PduBuilder {
-                event_type: TimelineEventType::RoomMember,
-                content: to_raw_value(&RoomMemberEventContent {
-                    membership: MembershipState::Invite,
-                    displayname: None,
-                    avatar_url: None,
-                    is_direct: None,
-                    third_party_invite: None,
-                    blurhash: None,
-                    reason: None,
-                    join_authorized_via_users_server: None,
-                })
-                .expect("event is valid, we just created it"),
-                unsigned: None,
-                state_key: Some(user_id.to_string()),
-                redacts: None,
-            },
-            &conduit_user,
-            &room_id,
-            &state_lock,
-        )?;
-        services().rooms.timeline.build_and_append_pdu(
-            PduBuilder {
-                event_type: TimelineEventType::RoomMember,
-                content: to_raw_value(&RoomMemberEventContent {
-                    membership: MembershipState::Join,
-                    displayname: Some(displayname),
-                    avatar_url: None,
-                    is_direct: None,
-                    third_party_invite: None,
-                    blurhash: None,
-                    reason: None,
-                    join_authorized_via_users_server: None,
-                })
-                .expect("event is valid, we just created it"),
-                unsigned: None,
-                state_key: Some(user_id.to_string()),
-                redacts: None,
-            },
-            user_id,
-            &room_id,
-            &state_lock,
-        )?;
+            // Set power level
+            let mut users = BTreeMap::new();
+            users.insert(conduit_user.to_owned(), 100.into());
+            users.insert(user_id.to_owned(), 100.into());
 
-        // Set power level
-        let mut users = BTreeMap::new();
-        users.insert(conduit_user.to_owned(), 100.into());
-        users.insert(user_id.to_owned(), 100.into());
+            services().rooms.timeline.build_and_append_pdu(
+                PduBuilder {
+                    event_type: TimelineEventType::RoomPowerLevels,
+                    content: to_raw_value(&RoomPowerLevelsEventContent {
+                        users,
+                        ..Default::default()
+                    })
+                    .expect("event is valid, we just created it"),
+                    unsigned: None,
+                    state_key: Some("".to_owned()),
+                    redacts: None,
+                },
+                &conduit_user,
+                &room_id,
+                &state_lock,
+            )?;
 
-        services().rooms.timeline.build_and_append_pdu(
-            PduBuilder {
-                event_type: TimelineEventType::RoomPowerLevels,
-                content: to_raw_value(&RoomPowerLevelsEventContent {
-                    users,
-                    ..Default::default()
-                })
-                .expect("event is valid, we just created it"),
-                unsigned: None,
-                state_key: Some("".to_owned()),
-                redacts: None,
-            },
-            &conduit_user,
-            &room_id,
-            &state_lock,
-        )?;
-
-        // Send welcome message
-        services().rooms.timeline.build_and_append_pdu(
+            // Send welcome message
+            services().rooms.timeline.build_and_append_pdu(
             PduBuilder {
                 event_type: TimelineEventType::RoomMessage,
                 content: to_raw_value(&RoomMessageEventContent::text_html(
@@ -1225,7 +1222,10 @@ impl Service {
             &state_lock,
         )?;
 
-        Ok(())
+            Ok(())
+        } else {
+            Ok(())
+        }
     }
 }
 
diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs
index 13193e52..b66fc645 100644
--- a/src/service/rooms/timeline/mod.rs
+++ b/src/service/rooms/timeline/mod.rs
@@ -448,7 +448,6 @@ impl Service {
                         .search
                         .index_pdu(shortroomid, &pdu_id, &body)?;
 
-                    let admin_room = services().admin.get_admin_room();
                     let server_user = format!("@conduit:{}", services().globals.server_name());
 
                     let to_conduit = body.starts_with(&format!("{server_user}: "))
@@ -461,8 +460,10 @@ impl Service {
                     let from_conduit = pdu.sender == server_user
                         && services().globals.emergency_password().is_none();
 
-                    if to_conduit && !from_conduit && admin_room == pdu.room_id {
-                        services().admin.process_message(body);
+                    if let Some(admin_room) = services().admin.get_admin_room()? {
+                        if to_conduit && !from_conduit && admin_room == pdu.room_id {
+                            services().admin.process_message(body);
+                        }
                     }
                 }
             }
@@ -815,84 +816,85 @@ impl Service {
         let (pdu, pdu_json) =
             self.create_hash_and_sign_event(pdu_builder, sender, room_id, state_lock)?;
 
-        let admin_room = services().admin.get_admin_room();
-        if admin_room == room_id {
-            match pdu.event_type() {
-                TimelineEventType::RoomEncryption => {
-                    warn!("Encryption is not allowed in the admins room");
-                    return Err(Error::BadRequest(
-                        ErrorKind::Forbidden,
-                        "Encryption is not allowed in the admins room.",
-                    ));
+        if let Some(admin_room) = services().admin.get_admin_room()? {
+            if admin_room == room_id {
+                match pdu.event_type() {
+                    TimelineEventType::RoomEncryption => {
+                        warn!("Encryption is not allowed in the admins room");
+                        return Err(Error::BadRequest(
+                            ErrorKind::Forbidden,
+                            "Encryption is not allowed in the admins room.",
+                        ));
+                    }
+                    TimelineEventType::RoomMember => {
+                        #[derive(Deserialize)]
+                        struct ExtractMembership {
+                            membership: MembershipState,
+                        }
+
+                        let target = pdu
+                            .state_key()
+                            .filter(|v| v.starts_with('@'))
+                            .unwrap_or(sender.as_str());
+                        let server_name = services().globals.server_name();
+                        let server_user = format!("@conduit:{}", server_name);
+                        let content = serde_json::from_str::<ExtractMembership>(pdu.content.get())
+                            .map_err(|_| Error::bad_database("Invalid content in pdu."))?;
+
+                        if content.membership == MembershipState::Leave {
+                            if target == server_user {
+                                warn!("Conduit user cannot leave from admins room");
+                                return Err(Error::BadRequest(
+                                    ErrorKind::Forbidden,
+                                    "Conduit user cannot leave from admins room.",
+                                ));
+                            }
+
+                            let count = services()
+                                .rooms
+                                .state_cache
+                                .room_members(room_id)
+                                .filter_map(|m| m.ok())
+                                .filter(|m| m.server_name() == server_name)
+                                .filter(|m| m != target)
+                                .count();
+                            if count < 2 {
+                                warn!("Last admin cannot leave from admins room");
+                                return Err(Error::BadRequest(
+                                    ErrorKind::Forbidden,
+                                    "Last admin cannot leave from admins room.",
+                                ));
+                            }
+                        }
+
+                        if content.membership == MembershipState::Ban && pdu.state_key().is_some() {
+                            if target == server_user {
+                                warn!("Conduit user cannot be banned in admins room");
+                                return Err(Error::BadRequest(
+                                    ErrorKind::Forbidden,
+                                    "Conduit user cannot be banned in admins room.",
+                                ));
+                            }
+
+                            let count = services()
+                                .rooms
+                                .state_cache
+                                .room_members(room_id)
+                                .filter_map(|m| m.ok())
+                                .filter(|m| m.server_name() == server_name)
+                                .filter(|m| m != target)
+                                .count();
+                            if count < 2 {
+                                warn!("Last admin cannot be banned in admins room");
+                                return Err(Error::BadRequest(
+                                    ErrorKind::Forbidden,
+                                    "Last admin cannot be banned in admins room.",
+                                ));
+                            }
+                        }
+                    }
+                    _ => {}
                 }
-                TimelineEventType::RoomMember => {
-                    #[derive(Deserialize)]
-                    struct ExtractMembership {
-                        membership: MembershipState,
-                    }
-
-                    let target = pdu
-                        .state_key()
-                        .filter(|v| v.starts_with('@'))
-                        .unwrap_or(sender.as_str());
-                    let server_name = services().globals.server_name();
-                    let server_user = format!("@conduit:{}", server_name);
-                    let content = serde_json::from_str::<ExtractMembership>(pdu.content.get())
-                        .map_err(|_| Error::bad_database("Invalid content in pdu."))?;
-
-                    if content.membership == MembershipState::Leave {
-                        if target == server_user {
-                            warn!("Conduit user cannot leave from admins room");
-                            return Err(Error::BadRequest(
-                                ErrorKind::Forbidden,
-                                "Conduit user cannot leave from admins room.",
-                            ));
-                        }
-
-                        let count = services()
-                            .rooms
-                            .state_cache
-                            .room_members(room_id)
-                            .filter_map(|m| m.ok())
-                            .filter(|m| m.server_name() == server_name)
-                            .filter(|m| m != target)
-                            .count();
-                        if count < 2 {
-                            warn!("Last admin cannot leave from admins room");
-                            return Err(Error::BadRequest(
-                                ErrorKind::Forbidden,
-                                "Last admin cannot leave from admins room.",
-                            ));
-                        }
-                    }
-
-                    if content.membership == MembershipState::Ban && pdu.state_key().is_some() {
-                        if target == server_user {
-                            warn!("Conduit user cannot be banned in admins room");
-                            return Err(Error::BadRequest(
-                                ErrorKind::Forbidden,
-                                "Conduit user cannot be banned in admins room.",
-                            ));
-                        }
-
-                        let count = services()
-                            .rooms
-                            .state_cache
-                            .room_members(room_id)
-                            .filter_map(|m| m.ok())
-                            .filter(|m| m.server_name() == server_name)
-                            .filter(|m| m != target)
-                            .count();
-                        if count < 2 {
-                            warn!("Last admin cannot be banned in admins room");
-                            return Err(Error::BadRequest(
-                                ErrorKind::Forbidden,
-                                "Last admin cannot be banned in admins room.",
-                            ));
-                        }
-                    }
-                }
-                _ => {}
             }
         }