diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua
index 870d049fda884118d19e6d505c402ce3934f7a19..67cef788e5544882bfac18e4787e551d1cc79d47 100644
--- a/src/lua/box_net_box.lua
+++ b/src/lua/box_net_box.lua
@@ -40,20 +40,18 @@ local GREETING_SIZE     = 128
 
 local TIMEOUT_INFINITY  = 500 * 365 * 86400
 
-local sequence_mt = { __serialize = 'sequence'}
-local mapping_mt = { __serialize = 'mapping'}
+local sequence_mt = { __serialize = 'sequence' }
+local mapping_mt = { __serialize = 'mapping' }
 
 local CONSOLE_FAKESYNC  = 15121974
 
 local function request(header, body)
-
     -- hint msgpack to always encode header and body as a map
     header = msgpack.encode(setmetatable(header, mapping_mt))
     body = msgpack.encode(setmetatable(body, mapping_mt))
 
     local len = msgpack.encode(string.len(header) + string.len(body))
 
-
     return len .. header .. body
 end
 
@@ -158,8 +156,7 @@ local proto = {
     end,
 
     -- select
-    select  = function(sync, spaceno, indexno, key, opts)
-
+    select = function(sync, spaceno, indexno, key, opts)
         if opts == nil then
             opts = {}
         end
@@ -358,7 +355,7 @@ local remote_methods = {
             end
 
             if port == nil then
-                
+
                 local address = urilib.parse(tostring(host))
                 if address == nil or address.service == nil then
                     box.error(box.error.PROC_LUA,
@@ -391,7 +388,7 @@ local remote_methods = {
             box.error(box.error.PROC_LUA,
                 "net.box: user is not defined")
         end
-            
+
 
         if self.host == nil then
             self.host = 'localhost'
@@ -451,7 +448,7 @@ local remote_methods = {
             local res = self:_request('call', true, proc_name, {...})
             return res.body[DATA]
         end
-        
+
         local eval_str = proc_name .. '('
         for i = 1, select('#', ...) do
             if i > 1 then
@@ -517,6 +514,10 @@ local remote_methods = {
         }
     end,
 
+    reload_schema = function(self)
+         self:_load_schema()
+    end,
+
     close = function(self)
         if self.state ~= 'closed' then
             self:_switch_state('closed')
@@ -582,7 +583,7 @@ local remote_methods = {
             if result ~= nil then
                 result = result[1]
             end
-            
+
             local hdr = { [SYNC] = CONSOLE_FAKESYNC, [TYPE] = 0 }
             local body = {}
 
@@ -611,7 +612,7 @@ local remote_methods = {
         if self.console then
             return self:_check_console_response(self)
         end
-    
+
         while true do
             if #self.rbuf < 5 then
                 break
@@ -762,12 +763,12 @@ local remote_methods = {
                         if not s then
                             self:_fatal(e)
                         end
-                            
+
                         xpcall(function() self:_load_schema() end,
                             function(e)
                                 log.info("Can't load schema: %s", tostring(e))
                             end)
-                       
+
                         if self.state ~= 'error' and self.state ~= 'closed' then
                             self:_switch_state('active')
                         end
@@ -779,11 +780,11 @@ local remote_methods = {
 
     _auth = function(self)
         if self.opts.user == nil or self.opts.password == nil then
-            self:_switch_state 'authen'
+            self:_switch_state('authen')
             return
         end
 
-        self:_switch_state 'auth'
+        self:_switch_state('auth')
 
         local auth_res = self:_request_internal('auth',
             false, self.opts.user, self.opts.password, self.handshake)
@@ -793,7 +794,7 @@ local remote_methods = {
             return
         end
 
-        self:_switch_state 'authen'
+        self:_switch_state('authen')
     end,
 
     -- states wakeup _read_worker
@@ -821,13 +822,12 @@ local remote_methods = {
         return false
     end,
 
-
     _load_schema = function(self)
-        if self.state ~= 'authen' then
-            self:_fatal 'Can not load schema from the state'
+        if self.state == 'closed' or self.state == 'error' then
+            self:_fatal('Can not load schema from the state')
             return
         end
-        
+
         self:_switch_state('schema')
 
         local spaces = self:_request_internal('select',
@@ -837,7 +837,6 @@ local remote_methods = {
 
         local sl = {}
 
-
         for _, space in pairs(spaces) do
             local name = space[3]
             local id = space[1]
@@ -851,7 +850,6 @@ local remote_methods = {
                 field_count     = field_count,
                 enabled         = true,
                 index           = {}
-
             }
             if #space > 5 and string.match(space[6], 'temporary') then
                 s.temporary = true
@@ -863,7 +861,6 @@ local remote_methods = {
 
             sl[id] = s
             sl[name] = s
-
         end
 
         for _, index in pairs(indexes) do
@@ -941,7 +938,7 @@ local remote_methods = {
         fiber.name('net.box.write')
         while self.state ~= 'closed' do
             self:_wait_state(self._rw_states)
-            
+
             if self.state == 'closed' then
                 break
             end
@@ -1017,7 +1014,7 @@ local remote_methods = {
     end,
 
     _request_raw = function(self, sync, request, raise)
-        
+
         local fid = fiber.id()
         if self.timeouts[fid] == nil then
             self.timeouts[fid] = TIMEOUT_INFINITY
@@ -1052,7 +1049,7 @@ local remote_methods = {
 
         if raise and response.hdr[TYPE] ~= OK then
             box.error({
-                code = response.hdr[TYPE],
+                code = bit.band(response.hdr[TYPE], bit.lshift(1, 15) - 1),
                 reason = response.body[ERROR]
             })
         end
@@ -1072,11 +1069,9 @@ local remote_methods = {
     end,
 
     _request_internal = function(self, name, raise, ...)
-
         local sync = self.proto:sync()
         local request = self.proto[name](sync, ...)
         return self:_request_raw(sync, request, raise)
-        
     end,
 
     -- private (low level) methods
@@ -1110,6 +1105,7 @@ setmetatable(remote, { __index = remote_methods })
 
 remote.self = {
     ping = function() return true end,
+    reload_schema = function() end,
     close = function() end,
     timeout = function(self) return self end,
     wait_connected = function(self) return true end,
@@ -1151,5 +1147,3 @@ setmetatable(remote.self, {
 })
 
 return remote
-
-
diff --git a/src/lua/digest.lua b/src/lua/digest.lua
index 3f5653be86145e88d8f376ed21873dc58ee1faef..1e41483f6622795b1e4d47b870e3fdc2edae0041 100644
--- a/src/lua/digest.lua
+++ b/src/lua/digest.lua
@@ -35,6 +35,7 @@ ffi.cdef[[
 local ssl
 if ssl == nil then
     local variants = {
+        'libssl.so.10',
         'libssl.so.1.0.0',
         'libssl.so.0.9.8',
         'libssl.so',
diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result
index b5af04d8a7ccdcf38bd52825ff6c8794d3a88125..3d0a204c5d6e15220e9209cde6544f09144a55e9 100644
--- a/test/box/box.net.box.result
+++ b/test/box/box.net.box.result
@@ -648,3 +648,116 @@ end;
 gh594()
 ---
 ...
+-- #636: Reload schema on demand
+sp = box.schema.create_space('test_old')
+---
+...
+sp:create_index('primary')
+---
+- unique: true
+  parts:
+  - type: NUM
+    fieldno: 1
+  id: 0
+  space_id: 512
+  name: primary
+  type: TREE
+...
+sp:insert{1, 2, 3}
+---
+- [1, 2, 3]
+...
+con = remote.new(box.cfg.listen)
+---
+...
+con:ping()
+---
+- true
+...
+con.space.test_old:select{}
+---
+- - [1, 2, 3]
+...
+con.space.test == nil
+---
+- true
+...
+sp = box.schema.create_space('test')
+---
+...
+sp:create_index('primary')
+---
+- unique: true
+  parts:
+  - type: NUM
+    fieldno: 1
+  id: 0
+  space_id: 513
+  name: primary
+  type: TREE
+...
+sp:insert{2, 3, 4}
+---
+- [2, 3, 4]
+...
+con.space.test == nil
+---
+- true
+...
+con:reload_schema()
+---
+- error: '[string "return con:reload_schema() "]:1: attempt to call method ''reload_schema''
+    (a nil value)'
+...
+con.space.test:select{}
+---
+- error: '[string "return con.space.test:select{} "]:1: attempt to index field ''test''
+    (a nil value)'
+...
+box.space.test:drop()
+---
+...
+box.space.test_old:drop()
+---
+...
+con:close()
+---
+...
+file_log = require('fio').open('tarantool.log', {'O_RDONLY', 'O_NONBLOCK'})
+---
+...
+file_log:seek(0, 'SEEK_END') ~= 0
+---
+- true
+...
+--# setopt delimiter ';'
+require('fiber').create(
+   function()
+         conn = require('net.box').new(box.cfg.listen)
+         conn.call('no_such_function', {})
+   end
+);
+---
+- status: suspended
+  name: lua
+  id: 151
+...
+while true do
+   local line = file_log:read(2048)
+   if line ~= nil then
+      if string.match(line, "ER_UNKNOWN") == nil then
+         return "Success"
+      else
+         return "Failure"
+      end
+   end
+   require('fiber').sleep(0.1)
+end;
+---
+- Success
+...
+--# setopt delimiter ''
+file_log:close()
+---
+- true
+...
diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua
index 65309c0321b16a19598fa61598e31da337251d45..a244dd421affa4e13e09f89a24b1be7ab91f2154 100644
--- a/test/box/box.net.box.test.lua
+++ b/test/box/box.net.box.test.lua
@@ -262,3 +262,52 @@ function gh594()
 end;
 --# setopt delimiter ''
 gh594()
+
+-- #636: Reload schema on demand
+sp = box.schema.create_space('test_old')
+sp:create_index('primary')
+sp:insert{1, 2, 3}
+
+con = remote.new(box.cfg.listen)
+con:ping()
+con.space.test_old:select{}
+con.space.test == nil
+
+sp = box.schema.create_space('test')
+sp:create_index('primary')
+sp:insert{2, 3, 4}
+
+con.space.test == nil
+con:reload_schema()
+con.space.test:select{}
+
+box.space.test:drop()
+box.space.test_old:drop()
+con:close()
+
+file_log = require('fio').open('tarantool.log', {'O_RDONLY', 'O_NONBLOCK'})
+file_log:seek(0, 'SEEK_END') ~= 0
+
+--# setopt delimiter ';'
+
+require('fiber').create(
+   function()
+         conn = require('net.box').new(box.cfg.listen)
+         conn.call('no_such_function', {})
+   end
+);
+while true do
+   local line = file_log:read(2048)
+   if line ~= nil then
+      if string.match(line, "ER_UNKNOWN") == nil then
+         return "Success"
+      else
+         return "Failure"
+      end
+   end
+   require('fiber').sleep(0.1)
+end;
+
+--# setopt delimiter ''
+
+file_log:close()