diff --git a/src/lua/utils.c b/src/lua/utils.c
index d5122ee2c137470be2429b23ea574186a0fbcc50..208b64eb115f3e2ca5dee3b0199f3664e0f147f2 100644
--- a/src/lua/utils.c
+++ b/src/lua/utils.c
@@ -667,7 +667,7 @@ luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg, int index,
 		} else if (num >= 0 && num < exp2(64)) {
 			field->type = MP_UINT;
 			field->ival = (uint64_t) num;
-		} else if (num > -exp2(63) && num < exp2(63)) {
+		} else if (num >= -exp2(63) && num < exp2(63)) {
 			field->type = MP_INT;
 			field->ival = (int64_t) num;
 		} else {
diff --git a/test/app-tap/lua/serializer_test.lua b/test/app-tap/lua/serializer_test.lua
index 1609f768f19989b1b45f6c68cc39728d1870111d..03855975681390d1346c1e56e4e6d458c4f971fc 100644
--- a/test/app-tap/lua/serializer_test.lua
+++ b/test/app-tap/lua/serializer_test.lua
@@ -101,7 +101,7 @@ local function test_unsigned(test, s)
 end
 
 local function test_signed(test, s)
-    test:plan(52)
+    test:plan(53)
 
     rt(test, s, -1, 'number')
     rt(test, s, -1LL, 'number')
@@ -143,6 +143,10 @@ local function test_signed(test, s)
 
     rt(test, s, ffi.new('short', -128), 'number')
     rt(test, s, ffi.new('int', -128), 'number')
+
+    -- gh-4672: Make sure that -2^63 encoded as INTEGER.
+    test:ok(s.encode(-9223372036854775808LL) == s.encode(-2^63),
+            '-2^63 encoded as INTEGER')
 end
 
 local function test_double(test, s)
diff --git a/test/box/gh-4672-min-integer-value-in-serializer.result b/test/box/gh-4672-min-integer-value-in-serializer.result
new file mode 100644
index 0000000000000000000000000000000000000000..f4d7adb4d33b15f018545ab0c96b4bbbbfd950a9
--- /dev/null
+++ b/test/box/gh-4672-min-integer-value-in-serializer.result
@@ -0,0 +1,97 @@
+-- test-run result file version 2
+remote = require('net.box')
+ | ---
+ | ...
+env = require('test_run')
+ | ---
+ | ...
+test_run = env.new()
+ | ---
+ | ...
+
+--
+-- gh-4672: Due to an error in the serializer, -2^63 was
+-- serialized as double, although in accordance with the rules of
+-- serialization it should be serialized as an integer.
+--
+format={{name='u', type='unsigned'}, {name='i', type='integer'}}
+ | ---
+ | ...
+s = box.schema.space.create('serializer_test_space', {format=format})
+ | ---
+ | ...
+_ = s:create_index('ii')
+ | ---
+ | ...
+
+s:insert({1, -2^63})
+ | ---
+ | - [1, -9223372036854775808]
+ | ...
+s:insert({2, -9223372036854775808LL})
+ | ---
+ | - [2, -9223372036854775808]
+ | ...
+s:insert({3, 0})
+ | ---
+ | - [3, 0]
+ | ...
+s:update(3, {{'=', 'i', -2^63}})
+ | ---
+ | - [3, -9223372036854775808]
+ | ...
+s:insert({4, 0})
+ | ---
+ | - [4, 0]
+ | ...
+s:update(4, {{'=', 'i', -9223372036854775808LL}})
+ | ---
+ | - [4, -9223372036854775808]
+ | ...
+
+box.schema.user.grant('guest', 'read, write', 'space', 'serializer_test_space')
+ | ---
+ | ...
+
+cn = remote.connect(box.cfg.listen)
+ | ---
+ | ...
+s = cn.space.serializer_test_space
+ | ---
+ | ...
+
+s:insert({11, -2^63})
+ | ---
+ | - [11, -9223372036854775808]
+ | ...
+s:insert({12, -9223372036854775808LL})
+ | ---
+ | - [12, -9223372036854775808]
+ | ...
+s:insert({13, 0})
+ | ---
+ | - [13, 0]
+ | ...
+s:update(13, {{'=', 'i', -2^63}})
+ | ---
+ | - [13, -9223372036854775808]
+ | ...
+s:insert({14, 0})
+ | ---
+ | - [14, 0]
+ | ...
+s:update(14, {{'=', 'i', -9223372036854775808LL}})
+ | ---
+ | - [14, -9223372036854775808]
+ | ...
+
+cn:close()
+ | ---
+ | ...
+box.schema.user.revoke('guest', 'read, write', 'space', 'serializer_test_space')
+ | ---
+ | ...
+
+box.space.serializer_test_space:drop()
+ | ---
+ | ...
diff --git a/test/box/gh-4672-min-integer-value-in-serializer.test.lua b/test/box/gh-4672-min-integer-value-in-serializer.test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..f718a56147395d9b80385a9c37a7638e75a798f1
--- /dev/null
+++ b/test/box/gh-4672-min-integer-value-in-serializer.test.lua
@@ -0,0 +1,36 @@
+remote = require('net.box')
+env = require('test_run')
+test_run = env.new()
+
+--
+-- gh-4672: Due to an error in the serializer, -2^63 was
+-- serialized as double, although in accordance with the rules of
+-- serialization it should be serialized as an integer.
+--
+format={{name='u', type='unsigned'}, {name='i', type='integer'}}
+s = box.schema.space.create('serializer_test_space', {format=format})
+_ = s:create_index('ii')
+
+s:insert({1, -2^63})
+s:insert({2, -9223372036854775808LL})
+s:insert({3, 0})
+s:update(3, {{'=', 'i', -2^63}})
+s:insert({4, 0})
+s:update(4, {{'=', 'i', -9223372036854775808LL}})
+
+box.schema.user.grant('guest', 'read, write', 'space', 'serializer_test_space')
+
+cn = remote.connect(box.cfg.listen)
+s = cn.space.serializer_test_space
+
+s:insert({11, -2^63})
+s:insert({12, -9223372036854775808LL})
+s:insert({13, 0})
+s:update(13, {{'=', 'i', -2^63}})
+s:insert({14, 0})
+s:update(14, {{'=', 'i', -9223372036854775808LL}})
+
+cn:close()
+box.schema.user.revoke('guest', 'read, write', 'space', 'serializer_test_space')
+
+box.space.serializer_test_space:drop()