diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua
index b8169e71f58a09859f1952440edc848facfe3b1b..3aeb1e34553e588488c4ef68cb31620b91a8656e 100644
--- a/src/lua/box_net_box.lua
+++ b/src/lua/box_net_box.lua
@@ -619,21 +619,24 @@ local remote_methods = {
 
             local len, off = msgpack.decode(self.rbuf)
             -- wait for correct package length
-            if len + off - 1 > #self.rbuf then
+            local roff = off + len - 1
+            if roff > #self.rbuf then
                 break
             end
 
 
             local hdr, body
             hdr, off = msgpack.decode(self.rbuf, off)
-            if off < #self.rbuf then
+            -- assert(off <= roff + 1)
+            if off < roff then
                 body, off = msgpack.decode(self.rbuf, off)
+                -- assert(off == roff + 1)
                 -- disable YAML flow output (useful for admin console)
                 setmetatable(body, mapping_mt)
             else
                 body = {}
             end
-            self.rbuf = string.sub(self.rbuf, off + 1)
+            self.rbuf = string.sub(self.rbuf, off)
 
             local sync = hdr[SYNC]
 
diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result
index 58c38375be26804809d6ce1e6d56307612c8f09a..b5af04d8a7ccdcf38bd52825ff6c8794d3a88125 100644
--- a/test/box/box.net.box.result
+++ b/test/box/box.net.box.result
@@ -634,3 +634,17 @@ cn:ping()
 cn:close()
 ---
 ...
+-- #594: bad argument #1 to 'setmetatable' (table expected, got number)
+--# setopt delimiter ';'
+function gh594()
+    local cn = remote:new(box.cfg.listen)
+    local ping = fiber.create(function() cn:ping() end)
+    cn:call('dostring', 'return 2 + 2')
+    cn:close()
+end;
+---
+...
+--# setopt delimiter ''
+gh594()
+---
+...
diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua
index 9803bc9c5061ea4750a355e8290ebea3385dc06e..65309c0321b16a19598fa61598e31da337251d45 100644
--- a/test/box/box.net.box.test.lua
+++ b/test/box/box.net.box.test.lua
@@ -252,3 +252,13 @@ cn = remote.new(uri, { password = 'test' })
 cn:ping()
 cn:close()
 
+-- #594: bad argument #1 to 'setmetatable' (table expected, got number)
+--# setopt delimiter ';'
+function gh594()
+    local cn = remote:new(box.cfg.listen)
+    local ping = fiber.create(function() cn:ping() end)
+    cn:call('dostring', 'return 2 + 2')
+    cn:close()
+end;
+--# setopt delimiter ''
+gh594()