diff --git a/CHANGES.md b/CHANGES.md
index 051ab130b2132c96d970c3258f7c10497a7b36d3..3c92bedda3d6b9511898dfa4a008da64f6a0b646 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,12 @@
+# Synapse 1.124.0rc2 (2025-02-05)
+
+### Bugfixes
+
+- Fix regression where persisting events in some rooms could fail after a previous unclean shutdown. Introduced in v1.124.0rc1. ([\#18137](https://github.com/element-hq/synapse/issues/18137))
+
+
+
+
 # Synapse 1.124.0rc1 (2025-02-04)
 
 ### Bugfixes
diff --git a/debian/changelog b/debian/changelog
index 0b6d50daaacd3a3901095122381664750363600c..8c84eecb20d16b24def85b5a7ab4cde7344752f0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+matrix-synapse-py3 (1.124.0~rc2) stable; urgency=medium
+
+  * New Synapse release 1.124.0rc2.
+
+ -- Synapse Packaging team <packages@matrix.org>  Wed, 05 Feb 2025 16:35:53 +0000
+
 matrix-synapse-py3 (1.124.0~rc1) stable; urgency=medium
 
   * New Synapse release 1.124.0rc1.
diff --git a/pyproject.toml b/pyproject.toml
index 8febdc4c23a1eaae44b1645ae36da9a23a140ad8..3f577a19732190162c5f653414e65e16e05ab381 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -97,7 +97,7 @@ module-name = "synapse.synapse_rust"
 
 [tool.poetry]
 name = "matrix-synapse"
-version = "1.124.0rc1"
+version = "1.124.0rc2"
 description = "Homeserver for the Matrix decentralised comms protocol"
 authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
 license = "AGPL-3.0-or-later"
diff --git a/synapse/storage/databases/state/deletion.py b/synapse/storage/databases/state/deletion.py
index 4853e5aa2f0d0b48d60a1880684b10385bb9a187..d0949261f2baccaf9adbfb7fdf8fa7084f88c5fb 100644
--- a/synapse/storage/databases/state/deletion.py
+++ b/synapse/storage/databases/state/deletion.py
@@ -95,8 +95,18 @@ class StateDeletionDataStore:
         self.db_pool = database
         self._instance_name = hs.get_instance_name()
 
-        # TODO: Clear from `state_groups_persisting` any holdovers from previous
-        # running instance.
+        with db_conn.cursor(txn_name="_clear_existing_persising") as txn:
+            self._clear_existing_persising(txn)
+
+    def _clear_existing_persising(self, txn: LoggingTransaction) -> None:
+        """On startup we clear any entries in `state_groups_persisting` that
+        match our instance name, in case of a previous unclean shutdown"""
+
+        self.db_pool.simple_delete_txn(
+            txn,
+            table="state_groups_persisting",
+            keyvalues={"instance_name": self._instance_name},
+        )
 
     async def check_state_groups_and_bump_deletion(
         self, state_groups: AbstractSet[int]