diff --git a/src/client_server/room.rs b/src/client_server/room.rs
index 1fcf2d6ce709218ba3fb2a4b0cc90439d044492d..d5819611309c474ce20163de23dbb9758a1e66d1 100644
--- a/src/client_server/room.rs
+++ b/src/client_server/room.rs
@@ -233,10 +233,9 @@ pub async fn create_room_route(
 
     // 5. Events listed in initial_state
     for event in &body.initial_state {
-        let pdu_builder = serde_json::from_str::<PduBuilder>(
-            &serde_json::to_string(&event).expect("AnyInitialStateEvent::to_string always works"),
-        )
-        .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid initial state event."))?;
+        let pdu_builder = PduBuilder::from(event.deserialize().map_err(|_| {
+            Error::BadRequest(ErrorKind::InvalidParam, "Invalid initial state event.")
+        })?);
 
         // Silently skip encryption events if they are not allowed
         if pdu_builder.event_type == EventType::RoomEncryption && !db.globals.allow_encryption() {
diff --git a/src/pdu.rs b/src/pdu.rs
index a72f04d2666b1cd905639b8461b592eb203cd81e..2167971a28169e491ab526cf498bab0bdef0dde0 100644
--- a/src/pdu.rs
+++ b/src/pdu.rs
@@ -2,9 +2,9 @@
 use log::error;
 use ruma::{
     events::{
-        pdu::EventHash, room::member::MemberEventContent, AnyEphemeralRoomEvent, AnyRoomEvent,
-        AnyStateEvent, AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventType,
-        StateEvent,
+        pdu::EventHash, room::member::MemberEventContent, AnyEphemeralRoomEvent,
+        AnyInitialStateEvent, AnyRoomEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncRoomEvent,
+        AnySyncStateEvent, EventType, StateEvent,
     },
     serde::{CanonicalJsonObject, CanonicalJsonValue, Raw},
     state_res, EventId, MilliSecondsSinceUnixEpoch, RoomId, RoomVersionId, ServerName,
@@ -346,3 +346,17 @@ pub struct PduBuilder {
     pub state_key: Option<String>,
     pub redacts: Option<EventId>,
 }
+
+/// Direct conversion prevents loss of the empty `state_key` that ruma requires.
+impl From<AnyInitialStateEvent> for PduBuilder {
+    fn from(event: AnyInitialStateEvent) -> Self {
+        Self {
+            event_type: EventType::from(event.event_type()),
+            content: serde_json::value::to_value(event.content())
+                .expect("AnyStateEventContent came from JSON and can thus turn back into JSON."),
+            unsigned: None,
+            state_key: Some(event.state_key().to_owned()),
+            redacts: None,
+        }
+    }
+}