diff --git a/test/box/before_replace.result b/test/box/before_replace.result
index 10f4699c0b82b983a01348be7df965d46d446334..4f47b9fade020932e61b30b231ef93366116d7f5 100644
--- a/test/box/before_replace.result
+++ b/test/box/before_replace.result
@@ -664,6 +664,104 @@ row.BODY.space_id == s.id
 ---
 - true
 ...
+-- gh-3128 before_replace with run_triggers
+s2 = box.schema.space.create("test2")
+---
+...
+_ = s2:create_index("prim")
+---
+...
+before_replace1 = function() s2:insert{1} s:run_triggers(false) end
+---
+...
+before_replace2 = function() s2:insert{2} end
+---
+...
+on_replace = function() s2:insert{3} end
+---
+...
+type(s:on_replace(on_replace))
+---
+- function
+...
+type(s:before_replace(before_replace1))
+---
+- function
+...
+type(s:before_replace(before_replace2))
+---
+- function
+...
+s:insert{1, 1}
+---
+...
+s2:select{}
+---
+- - [1]
+  - [2]
+...
+s:truncate()
+---
+...
+s2:truncate()
+---
+...
+s:on_replace(nil, on_replace)
+---
+...
+s:before_replace(nil, before_replace1)
+---
+...
+s:before_replace(nil, before_replace2)
+---
+...
+--
+-- gh-3128
+-- If at least one before trigger returns old
+-- insertion will be aborted, but other before triggers
+-- will be executed
+before_replace1 = function(old, new) s2:insert{1} return old end
+---
+...
+before_replace2 = function(old, new) s2:insert{2} end
+---
+...
+type(s:on_replace(on_replace))
+---
+- function
+...
+type(s:before_replace(before_replace1))
+---
+- function
+...
+type(s:before_replace(before_replace2))
+---
+- function
+...
+s:insert{1, 1}
+---
+...
+s:select{}
+---
+- []
+...
+s2:select{}
+---
+- - [1]
+  - [2]
+...
+s:on_replace(nil, on_replace)
+---
+...
+s:before_replace(nil, before_replace1)
+---
+...
+s:before_replace(nil, before_replace2)
+---
+...
+s2:drop()
+---
+...
 s:drop()
 ---
 ...
diff --git a/test/box/before_replace.test.lua b/test/box/before_replace.test.lua
index 01a386d9dc8e76c468a424a0af4fb4f98d10d93b..22733c1de1e180dc98175ad91e04f39dd6c79611 100644
--- a/test/box/before_replace.test.lua
+++ b/test/box/before_replace.test.lua
@@ -223,4 +223,44 @@ state, row = fun(param, state)
 row.HEADER.type
 row.BODY.space_id == s.id
 
+-- gh-3128 before_replace with run_triggers
+s2 = box.schema.space.create("test2")
+_ = s2:create_index("prim")
+before_replace1 = function() s2:insert{1} s:run_triggers(false) end
+before_replace2 = function() s2:insert{2} end
+on_replace = function() s2:insert{3} end
+
+type(s:on_replace(on_replace))
+type(s:before_replace(before_replace1))
+type(s:before_replace(before_replace2))
+
+s:insert{1, 1}
+s2:select{}
+s:truncate()
+s2:truncate()
+
+s:on_replace(nil, on_replace)
+s:before_replace(nil, before_replace1)
+s:before_replace(nil, before_replace2)
+
+--
+-- gh-3128
+-- If at least one before trigger returns old
+-- insertion will be aborted, but other before triggers
+-- will be executed
+before_replace1 = function(old, new) s2:insert{1} return old end
+before_replace2 = function(old, new) s2:insert{2} end
+
+type(s:on_replace(on_replace))
+type(s:before_replace(before_replace1))
+type(s:before_replace(before_replace2))
+
+s:insert{1, 1}
+s:select{}
+s2:select{}
+
+s:on_replace(nil, on_replace)
+s:before_replace(nil, before_replace1)
+s:before_replace(nil, before_replace2)
+s2:drop()
 s:drop()