diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 359fc40c44ffd4cf3f5b9f8d26ec222676361727..7e6798a1c9bad38380145a3c553fd68a7659fc39 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -284,6 +284,7 @@ local function normalize_update_ops(ops)
     end
     return ops
 end
+internal.normalize_update_ops = normalize_update_ops -- export for net.box
 
 local iterator_t = ffi.typeof('struct iterator')
 ffi.metatype(iterator_t, {
diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua
index bd9e1463147bab2edc770468a6055e65f3d19ad0..b176a93eab7e3c0621dbeb714ef3d9e217acb7ee 100644
--- a/src/lua/box_net_box.lua
+++ b/src/lua/box_net_box.lua
@@ -158,6 +158,7 @@ local proto = {
 
     -- update
     update = function(sync, spaceno, key, oplist)
+        oplist = require('box.internal').normalize_update_ops(oplist)
         return request(
             { [SYNC] = sync, [TYPE] = UPDATE },
             { [KEY] = keyfy(key),   [TUPLE]  = oplist, [SPACE_ID] = spaceno }
diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result
index 9b6c3126cd93586a66972d49a01f363ba48072e2..16a4131fdc8bf6ce764589e4b029168da7e88dfc 100644
--- a/test/box/box.net.box.result
+++ b/test/box/box.net.box.result
@@ -138,7 +138,7 @@ cn.space.net_box_test_space:insert{234, 1,2,3}
 ...
 cn.space.net_box_test_space.insert{234, 1,2,3}
 ---
-- error: 'builtin/net.box.lua:236: Use space:method(...) instead space.method(...)'
+- error: 'builtin/net.box.lua:237: Use space:method(...) instead space.method(...)'
 ...
 cn.space.net_box_test_space:replace{354, 1,2,3}
 ---
@@ -181,11 +181,11 @@ cn.space.net_box_test_space:select{123}
 ---
 - - [123, 345]
 ...
-cn.space.net_box_test_space:update({123}, { { '+', 1, 1 } })
+cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } })
 ---
 - [123, 346]
 ...
-cn.space.net_box_test_space:update(123, { { '+', 1, 1 } })
+cn.space.net_box_test_space:update(123, { { '+', 2, 1 } })
 ---
 - [123, 347]
 ...
@@ -193,7 +193,7 @@ cn.space.net_box_test_space:select{123}
 ---
 - - [123, 347]
 ...
-cn.space.net_box_test_space:update({123}, { { '=', 0, 2 } })
+cn.space.net_box_test_space:update({123}, { { '=', 1, 2 } })
 ---
 - [2, 347]
 ...
@@ -205,7 +205,7 @@ cn.space.net_box_test_space:select({234}, { iterator = 'LT' })
 ---
 - - [2, 347]
 ...
-cn.space.net_box_test_space:update({1}, { { '+', 1, 2 } })
+cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } })
 ---
 ...
 cn.space.net_box_test_space:delete{1}
@@ -218,6 +218,35 @@ cn.space.net_box_test_space:delete{2}
 cn.space.net_box_test_space:delete{2}
 ---
 ...
+-- test one-based indexing in splice operation (see update.test.lua)
+cn.space.net_box_test_space:replace({10, 'abcde'})
+---
+- [10, 'abcde']
+...
+cn.space.net_box_test_space:update(10,  {{':', 2, 0, 0, '!'}})
+---
+- error: 'SPLICE error on field 2: offset is out of bound'
+...
+cn.space.net_box_test_space:update(10,  {{':', 2, 1, 0, '('}})
+---
+- [10, '(abcde']
+...
+cn.space.net_box_test_space:update(10,  {{':', 2, 2, 0, '({'}})
+---
+- [10, '(({abcde']
+...
+cn.space.net_box_test_space:update(10,  {{':', 2, -1, 0, ')'}})
+---
+- [10, '(({abcde)']
+...
+cn.space.net_box_test_space:update(10,  {{':', 2, -2, 0, '})'}})
+---
+- [10, '(({abcde}))']
+...
+cn.space.net_box_test_space:delete{10}
+---
+- [10, '(({abcde}))']
+...
 cn.space.net_box_test_space:select({}, { iterator = 'ALL' })
 ---
 - - [234, 1, 2, 3]
diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua
index 7c8aaf6518d8befbad48511c4009d6baaa7e0e2d..2df3b8f6aae33da5b6f488636ec6b1c69d2aa73c 100644
--- a/test/box/box.net.box.test.lua
+++ b/test/box/box.net.box.test.lua
@@ -62,20 +62,29 @@ cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 })
 cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 })
 
 cn.space.net_box_test_space:select{123}
-cn.space.net_box_test_space:update({123}, { { '+', 1, 1 } })
-cn.space.net_box_test_space:update(123, { { '+', 1, 1 } })
+cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } })
+cn.space.net_box_test_space:update(123, { { '+', 2, 1 } })
 cn.space.net_box_test_space:select{123}
 
-cn.space.net_box_test_space:update({123}, { { '=', 0, 2 } })
+cn.space.net_box_test_space:update({123}, { { '=', 1, 2 } })
 cn.space.net_box_test_space:select{2}
 cn.space.net_box_test_space:select({234}, { iterator = 'LT' })
 
-cn.space.net_box_test_space:update({1}, { { '+', 1, 2 } })
+cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } })
 
 cn.space.net_box_test_space:delete{1}
 cn.space.net_box_test_space:delete{2}
 cn.space.net_box_test_space:delete{2}
 
+-- test one-based indexing in splice operation (see update.test.lua)
+cn.space.net_box_test_space:replace({10, 'abcde'})
+cn.space.net_box_test_space:update(10,  {{':', 2, 0, 0, '!'}})
+cn.space.net_box_test_space:update(10,  {{':', 2, 1, 0, '('}})
+cn.space.net_box_test_space:update(10,  {{':', 2, 2, 0, '({'}})
+cn.space.net_box_test_space:update(10,  {{':', 2, -1, 0, ')'}})
+cn.space.net_box_test_space:update(10,  {{':', 2, -2, 0, '})'}})
+cn.space.net_box_test_space:delete{10}
+
 cn.space.net_box_test_space:select({}, { iterator = 'ALL' })
 
 cn.space.net_box_test_space.index.primary:min()