diff --git a/jstests/noPassthrough/SERVER-87678-unstick-rst.js b/jstests/noPassthrough/SERVER-87678-unstick-rst.js
new file mode 100644
index 00000000000..d76a2d1cf9a
--- /dev/null
+++ b/jstests/noPassthrough/SERVER-87678-unstick-rst.js
@@ -0,0 +1,60 @@
+import {configureFailPoint} from "jstests/libs/fail_point_util.js";
+
+const rst = new ReplSetTest({nodes: 1});
+rst.startSet();
+rst.initiate();
+
+let conn = rst.getPrimary();
+let db = conn.getDB('test');
+
+// Start at FCV 7.0 where featureFlagDisallowBucketCollectionWithoutTimeseriesOptions is disabled
+assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: "7.0", confirm: true}));
+
+// Reproduce SERVER-87678
+assert.commandWorked(db.createCollection('coll', {timeseries: {timeField: 't', metaField: 'm'}}));
+const hangBeforeCreateIndexForTimeseries =
+    configureFailPoint(conn, "hangBeforeCreateIndexForTimeseries");
+const awaitShellCreateIndex = startParallelShell(
+    '{ assert.commandWorked(db.getSiblingDB("test").coll.createIndex({time:1, meta: 1})); }',
+    conn.port);
+hangBeforeCreateIndexForTimeseries.wait();
+assert.commandWorked(db.runCommand({drop: 'coll'}));
+hangBeforeCreateIndexForTimeseries.off();
+awaitShellCreateIndex();
+
+// Verify that the catalog contains a buckets collection without timeseries options
+assert(!db.getCollectionNames().includes("coll"));
+assert(db.getCollectionNames().includes("system.buckets.coll"));
+assert(!db.system.buckets.coll.aggregate([{$listCatalog: {}}]).toArray()[0].md.timeseries);
+
+// Start a FCV upgrade so that it gets stuck
+assert.commandFailedWithCode(
+    db.adminCommand({setFeatureCompatibilityVersion: "8.0", confirm: true}),
+    ErrorCodes.CannotUpgrade);
+
+const fcvBefore = conn.getDB("admin").system.version.findOne({_id: "featureCompatibilityVersion"});
+assert.eq("7.0", fcvBefore.version);
+assert.eq("8.0", fcvBefore.targetVersion);
+
+// Restart with the featureFlagDisallowBucketCollectionWithoutTimeseriesOptions flag disabled
+rst.stopSet(null /* signal */, true /* forRestart */);
+rst.startSet({
+    restart: true,
+    setParameter: {featureFlagDisallowBucketCollectionWithoutTimeseriesOptions: false}
+});
+
+conn = rst.getPrimary();
+db = conn.getDB('test');
+
+// Try to resume the in-progress upgrade
+assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: "8.0", confirm: true}));
+
+const fcvAfter = conn.getDB("admin").system.version.findOne({_id: "featureCompatibilityVersion"});
+assert.eq("8.0", fcvAfter.version);
+assert.eq(null, fcvAfter.targetVersion);
+
+print("FINAL FCV:" + tojson(fcvAfter));
+print("FINAL CATALOG:" +
+      tojson(db.getSiblingDB("admin").aggregate([{$listCatalog: {}}]).toArray()));
+
+rst.stopSet();
diff --git a/jstests/noPassthrough/SERVER-87678-unstick-st.js b/jstests/noPassthrough/SERVER-87678-unstick-st.js
new file mode 100644
index 00000000000..273b0f5897c
--- /dev/null
+++ b/jstests/noPassthrough/SERVER-87678-unstick-st.js
@@ -0,0 +1,63 @@
+import {configureFailPoint} from "jstests/libs/fail_point_util.js";
+
+const st = new ShardingTest({shards: 2});
+
+let conn = st.s;
+let connRs = st.rs0.getPrimary();
+let db = conn.getDB("test");
+
+// Start at FCV 7.0 where featureFlagDisallowBucketCollectionWithoutTimeseriesOptions is disabled
+assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: "7.0", confirm: true}));
+
+// Reproduce SERVER-87678
+assert.commandWorked(db.adminCommand({enableSharding: "test", primaryShard: st.shard0.shardName}));
+assert.commandWorked(db.createCollection('coll', {timeseries: {timeField: 't', metaField: 'm'}}));
+assert.commandWorked(db.adminCommand({shardCollection: 'test.coll', key: {m: 1}}));
+assert.commandWorked(db.adminCommand({split: 'test.system.buckets.coll', middle: {meta: 0}}));
+assert.commandWorked(db.adminCommand(
+    {moveChunk: 'test.system.buckets.coll', find: {meta: 0}, to: st.shard1.shardName}));
+const hangBeforeCreateIndexForTimeseries =
+    configureFailPoint(connRs, "hangBeforeCreateIndexForTimeseries");
+const awaitShellCreateIndex = startParallelShell(
+    '{ assert.commandWorked(db.getSiblingDB("test").coll.createIndex({time:1, meta: 1})); }',
+    connRs.port);
+hangBeforeCreateIndexForTimeseries.wait();
+assert.commandWorked(db.runCommand({drop: 'coll'}));
+hangBeforeCreateIndexForTimeseries.off();
+awaitShellCreateIndex();
+
+// Verify that the catalog contains a buckets collection without timeseries options
+assert(!db.getCollectionNames().includes("coll"));
+assert(db.getCollectionNames().includes("system.buckets.coll"));
+assert(!db.system.buckets.coll.aggregate([{$listCatalog: {}}]).toArray()[0].md.timeseries);
+
+// Start a FCV upgrade so that it gets stuck
+assert.commandFailedWithCode(
+    db.adminCommand({setFeatureCompatibilityVersion: "8.0", confirm: true}),
+    ErrorCodes.CannotUpgrade);
+
+const fcvBefore = conn.getDB("admin").system.version.findOne({_id: "featureCompatibilityVersion"});
+assert.eq("7.0", fcvBefore.version);
+assert.eq("8.0", fcvBefore.targetVersion);
+
+// Restart with the featureFlagDisallowBucketCollectionWithoutTimeseriesOptions flag disabled
+st.stopAllShards({}, true /* forRestart */);
+st.restartAllShards(
+    {setParameter: {featureFlagDisallowBucketCollectionWithoutTimeseriesOptions: false}});
+
+conn = st.s;
+connRs = st.rs0.getPrimary();
+db = conn.getDB("test");
+
+// Try to resume the in-progress upgrade
+assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: "8.0", confirm: true}));
+
+const fcvAfter = conn.getDB("admin").system.version.findOne({_id: "featureCompatibilityVersion"});
+assert.eq("8.0", fcvAfter.version);
+assert.eq(null, fcvAfter.targetVersion);
+
+print("FINAL FCV:" + tojson(fcvAfter));
+print("FINAL CATALOG:" +
+      tojson(db.getSiblingDB("admin").aggregate([{$listCatalog: {}}]).toArray()));
+
+st.stop();
diff --git a/src/mongo/db/commands/create_indexes_cmd.cpp b/src/mongo/db/commands/create_indexes_cmd.cpp
index f2149bc6ab2..9ecd6c21377 100644
--- a/src/mongo/db/commands/create_indexes_cmd.cpp
+++ b/src/mongo/db/commands/create_indexes_cmd.cpp
@@ -131,6 +131,8 @@ MONGO_FAIL_POINT_DEFINE(hangCreateIndexesBeforeStartingIndexBuild);
 
 MONGO_FAIL_POINT_DEFINE(skipTTLIndexValidationOnCreateIndex);
 
+MONGO_FAIL_POINT_DEFINE(hangBeforeCreateIndexForTimeseries);
+
 constexpr auto kCommandName = "createIndexes"_sd;
 constexpr auto kAllIndexesAlreadyExist = "all indexes already exist"_sd;
 constexpr auto kIndexAlreadyExists = "index already exists"_sd;
@@ -819,6 +821,7 @@ public:
                 timeseriesCmdOwnership =
                     timeseries::makeTimeseriesCreateIndexesCommand(opCtx, origCmd, *options);
                 cmd = &timeseriesCmdOwnership.value();
+                hangBeforeCreateIndexForTimeseries.pauseWhileSet();
             }
 
             // If we encounter an IndexBuildAlreadyInProgress error for any of the requested index
