diff --git a/changelogs/unreleased/gh-10233-vy-snapshot-hang-fix.md b/changelogs/unreleased/gh-10233-vy-snapshot-hang-fix.md
index bf58a263f32d650d3d89f012262ac292d2660c52..151f366d769619832f993aa3cf1465a0961f181c 100644
--- a/changelogs/unreleased/gh-10233-vy-snapshot-hang-fix.md
+++ b/changelogs/unreleased/gh-10233-vy-snapshot-hang-fix.md
@@ -1,4 +1,4 @@
 ## bugfix/vinyl
 
-* Fixed a bug when `box.snapshot` hanged if executed concurrently with creation
-  of a new index (gh-10233).
+* Fixed a bug when a race between `box.snapshot` and the creation of a new
+  index could lead to a fiber hang (gh-10233, gh-10267).
diff --git a/src/box/vy_scheduler.c b/src/box/vy_scheduler.c
index 88a29a81eba79e1c6499f56899cdef1730c1bc22..f893e808c7f3714b14440fb0348e6e2a3890d40c 100644
--- a/src/box/vy_scheduler.c
+++ b/src/box/vy_scheduler.c
@@ -792,6 +792,8 @@ vy_scheduler_end_checkpoint(struct vy_scheduler *scheduler)
 		return;
 
 	scheduler->checkpoint_in_progress = false;
+	fiber_cond_broadcast(&scheduler->dump_cond);
+
 	if (scheduler->dump_pending) {
 		/*
 		 * Dump was triggered while checkpoint was
diff --git a/test/vinyl-luatest/gh_10233_index_build_vs_snapshot_test.lua b/test/vinyl-luatest/gh_10233_index_build_vs_snapshot_test.lua
index 3a9ddec7434560580dd6a892a22d209f1c8cb415..7e3e56af49281626475d7fe9c0a82b89d8dc8879 100644
--- a/test/vinyl-luatest/gh_10233_index_build_vs_snapshot_test.lua
+++ b/test/vinyl-luatest/gh_10233_index_build_vs_snapshot_test.lua
@@ -4,6 +4,7 @@ local t = require('luatest')
 local g = t.group()
 
 g.before_all(function(cg)
+    t.tarantool.skip_if_not_debug()
     cg.server = server:new()
     cg.server:start()
 end)
@@ -17,24 +18,53 @@ g.after_each(function(cg)
         if box.space.test ~= nil then
             box.space.test:drop()
         end
+        box.error.injection.set('ERRINJ_VY_DUMP_DELAY', false)
+        box.error.injection.set('ERRINJ_SNAP_COMMIT_DELAY', false)
     end)
 end)
 
-g.test_index_build_vs_snapshot = function(cg)
+g.test_case_1 = function(cg)
     cg.server:exec(function()
         local fiber = require('fiber')
         local s = box.schema.space.create('test', {engine = 'vinyl'})
         s:create_index('pk')
         s:insert({1, 1})
+        box.error.injection.set('ERRINJ_VY_DUMP_DELAY', true)
         local f1 = fiber.new(function()
             s:create_index('sk', {parts = {2, 'unsigned'}})
         end)
         f1:set_joinable(true)
+        fiber.sleep(0.1)
         local f2 = fiber.new(function()
             box.snapshot()
         end)
         f2:set_joinable(true)
         fiber.sleep(0.1)
+        box.error.injection.set('ERRINJ_VY_DUMP_DELAY', false)
+        local timeout = 5
+        t.assert_equals({f1:join(timeout)}, {true})
+        t.assert_equals({f2:join(timeout)}, {true})
+    end)
+end
+
+g.test_case_2 = function(cg)
+    cg.server:exec(function()
+        local fiber = require('fiber')
+        local s = box.schema.space.create('test', {engine = 'vinyl'})
+        s:create_index('pk')
+        s:insert({1, 1})
+        box.error.injection.set('ERRINJ_SNAP_COMMIT_DELAY', true)
+        local f1 = fiber.new(function()
+            box.snapshot()
+        end)
+        f1:set_joinable(true)
+        fiber.sleep(0.1)
+        local f2 = fiber.new(function()
+            s:create_index('sk', {parts = {2, 'unsigned'}})
+        end)
+        f2:set_joinable(true)
+        fiber.sleep(0.1)
+        box.error.injection.set('ERRINJ_SNAP_COMMIT_DELAY', false)
         local timeout = 5
         t.assert_equals({f1:join(timeout)}, {true})
         t.assert_equals({f2:join(timeout)}, {true})