diff --git a/src/box/box.cc b/src/box/box.cc
index e1bc1271665f37780be61539d87a4c409a576eff..a4af9caa02bd1d899767e99a25a3db0a49dca52c 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -125,6 +125,7 @@ box_check_replication_source(const char *source)
 static void
 box_check_wal_mode(const char *mode_name)
 {
+	assert(mode_name != NULL); /* checked in Lua */
 	int mode = strindex(wal_mode_STRS, mode_name, WAL_MODE_MAX);
 	if (mode == WAL_MODE_MAX) {
 		tnt_raise(ClientError, ER_CFG,
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 3b073880ea5dffe4eff97924ddbaf742256c45f2..47496a3e64d8c2c0834214b20cddab28acf7b028 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -59,7 +59,7 @@ local default_cfg = {
 
 -- types of available options
 -- could be comma separated lua types or 'any' if any type is allowed
-local template_cfg = {
+local template = {
     listen              = 'string, number',
     slab_alloc_arena    = 'number',
     slab_alloc_minimal  = 'number',
@@ -104,45 +104,9 @@ local dynamic_cfg = {
     snapshot_count          = box.internal.snap_daemon.set_snapshot_count,
 }
 
-local function reload_cfg(oldcfg, newcfg)
-    if newcfg == nil then
-        newcfg = {}
-    end
-    for key, val in pairs(newcfg) do
-        if dynamic_cfg[key] == nil then
-            box.error(box.error.RELOAD_CFG, key);
-        end
-        if val == "" then
-            val = nil
-        end
-        if wrapper_cfg[key] ~= nil then
-            val = wrapper_cfg[key](val)
-        end
-        dynamic_cfg[key](val)
-        rawset(oldcfg, key, val)
-    end
-    if type(box.on_reload_configuration) == 'function' then
-        box.on_reload_configuration()
-    end
-end
-
-local box = require('box')
--- Move all box members to box_saved
-local box_configured = {}
-for k, v in pairs(box) do
-    box_configured[k] = v
-    box[k] = nil
-end
-
-setmetatable(box, {
-    __index = function(table, index)
-        error("Please call box.cfg{} first")
-     end
-})
-
-local function check_param_table(table, template)
+local function prepare_cfg(table)
     if table == nil then
-        return
+        return {}
     end
     if type(table) ~= 'table' then
         error("Error: cfg should be a table")
@@ -151,9 +115,13 @@ local function check_param_table(table, template)
     if table.dont_check then
         return
     end
+    local newtable = {}
     for k,v in pairs(table) do
         if template[k] == nil then
             error("Error: cfg parameter '" .. k .. "' is unexpected")
+        elseif v == "" or v == nil then
+            -- "" and NULL = ffi.cast('void *', 0) set option to default value
+            v = default_cfg[k]
         elseif template[k] == 'any' then
             -- any type is ok
         elseif (string.find(template[k], ',') == nil) then
@@ -168,29 +136,48 @@ local function check_param_table(table, template)
                 error("Error: cfg parameter '" .. k .. "' should be one of types: " .. template[k])
             end
         end
+        if wrapper_cfg[k] ~= nil then
+            v = wrapper_cfg[k](v)
+        end
+        newtable[k] = v
     end
+    return newtable
 end
 
-
-local function update_param_table(table, defaults)
-    if table == nil then
-        table = {}
-    end
-    for k,v in pairs(defaults) do
-        if table[k] == nil then
-            table[k] = v
+local function reload_cfg(oldcfg, newcfg)
+    newcfg = prepare_cfg(newcfg)
+    for key, val in pairs(newcfg) do
+        if dynamic_cfg[key] == nil then
+            box.error(box.error.RELOAD_CFG, key);
         end
+        dynamic_cfg[key](val)
+        rawset(oldcfg, key, val)
+    end
+    if type(box.on_reload_configuration) == 'function' then
+        box.on_reload_configuration()
     end
-    return table
 end
 
-function box.cfg(cfg)
-    check_param_table(cfg, template_cfg)
-    cfg = update_param_table(cfg, default_cfg)
+local box = require('box')
+-- Move all box members to box_saved
+local box_configured = {}
+for k, v in pairs(box) do
+    box_configured[k] = v
+    box[k] = nil
+end
 
-    for k,v in pairs(wrapper_cfg) do
-        -- options that can be number or string
-        cfg[k] = wrapper_cfg[k](cfg[k])
+setmetatable(box, {
+    __index = function(table, index)
+        error("Please call box.cfg{} first")
+     end
+})
+
+function box.cfg(cfg)
+    cfg = prepare_cfg(cfg)
+    for k,v in pairs(default_cfg) do
+        if cfg[k] == nil then
+            cfg[k] = v
+        end
     end
     -- Restore box members from box_saved after initial configuration
     for k, v in pairs(box_configured) do
diff --git a/test/app/cfg.result b/test/app/cfg.result
index 60f07692ade6cf0b4b14e0acd40124a0a2176809..38f4a9c0db8c3de4ad176a7e8d11d5b527ce1b80 100644
--- a/test/app/cfg.result
+++ b/test/app/cfg.result
@@ -1,2 +1,10 @@
-false	[string "-- load_cfg.lua - internal file..."]:139: Please call box.cfg{} first
-true	table
+TAP version 13
+1..8
+ok - exception on unconfigured box
+ok - configured box
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode change
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode change
+ok - cfg.wal_mode default value
diff --git a/test/app/cfg.test.lua b/test/app/cfg.test.lua
index bce98a2db290b603bec2a20e71572090c8a3ea2a..d768107c2cae79144649420f3a1ae68ca9b86e91 100755
--- a/test/app/cfg.test.lua
+++ b/test/app/cfg.test.lua
@@ -1,19 +1,48 @@
 #!/usr/bin/env tarantool
 
+local tap = require('tap')
+local test = tap.test('cfg')
+test:plan(8)
+
 --------------------------------------------------------------------------------
 -- All box members must raise an exception on access if box.cfg{} wasn't called
 --------------------------------------------------------------------------------
 
 local box = require('box')
-local function test()
+local function testfun()
     return type(box.space)
 end
 
-print(pcall(test))
+local status, result = pcall(testfun)
+
+test:ok(not status and result:match('Please call box.cfg{}'),
+    'exception on unconfigured box')
+
 box.cfg{
     logger="tarantool.log",
     slab_alloc_arena=0.1,
+    wal_mode = "", -- "" means default value
 }
-print(pcall(test))
 
+status, result = pcall(testfun)
+test:ok(status and result == 'table', 'configured box')
+
+--------------------------------------------------------------------------------
+-- gh-534: Segmentation fault after two bad wal_mode settings
+--------------------------------------------------------------------------------
+
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = ""}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = "none"}
+test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change")
+-- "" or NULL resets option to default value
+box.cfg{wal_mode = ""}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = "none"}
+test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change")
+box.cfg{wal_mode = require('msgpack').NULL}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+
+test:check()
 os.exit(0)
diff --git a/test/box/cfg.result b/test/box/cfg.result
index 86c19dbde9033cefeba93ac7d8585460cd4838cc..a8d5db94014fd2a4079a8c9ba6671246254306a6 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -2,7 +2,7 @@
 --# push filter 'admin: .*' to 'admin: <uri>'
 box.cfg.nosuchoption = 1
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:204: Attempt to modify a read-only
+- error: '[string "-- load_cfg.lua - internal file..."]:191: Attempt to modify a read-only
     table'
 ...
 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end