diff --git a/changelogs/unreleased/gh-5222-key_def-type-null.md b/changelogs/unreleased/gh-5222-key_def-type-null.md
new file mode 100644
index 0000000000000000000000000000000000000000..f89c9d2cf4d6c74a22e155bb428df2dcf0f67bcc
--- /dev/null
+++ b/changelogs/unreleased/gh-5222-key_def-type-null.md
@@ -0,0 +1,4 @@
+## bugfix/box
+
+* Fixed a bug when `type = box.NULL` in `key_def.new()` resulted in
+  `type = 'unsigned'` (gh-5222).
diff --git a/src/box/lua/key_def.c b/src/box/lua/key_def.c
index 1147b9c32648d2ee20cdbd7ecf1031e3fbbdfec5..321bdad3f8e3380ba5f1e9f361a8aceb7a673137 100644
--- a/src/box/lua/key_def.c
+++ b/src/box/lua/key_def.c
@@ -124,8 +124,10 @@ luaT_key_def_set_part(struct lua_State *L, struct key_part_def *part,
 	/* Set part->type. */
 	lua_pushstring(L, "type");
 	lua_gettable(L, -2);
-	if (lua_isnil(L, -1)) {
-		diag_set(IllegalParams, "type must not be nil");
+	if (!lua_isstring(L, -1)) {
+		diag_set(IllegalParams,
+			 "Wrong field type: expected string, got %s",
+			 lua_typename(L, lua_type(L, -1)));
 		return -1;
 	}
 	size_t type_len;
diff --git a/test/box-luatest/gh_5222_key_def_invalid_type_test.lua b/test/box-luatest/gh_5222_key_def_invalid_type_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..ebe2f4a2495e56219a469079c14350f1dcf2632b
--- /dev/null
+++ b/test/box-luatest/gh_5222_key_def_invalid_type_test.lua
@@ -0,0 +1,28 @@
+local t = require('luatest')
+local g = t.group('gh-5222')
+
+g.test_key_def_invalid_type = function()
+    local key_def = require('key_def')
+
+    t.assert_error_msg_content_equals("Wrong field type: expected string, got nil", function()
+        key_def.new({{field = 1, type = nil}})
+    end)
+    t.assert_error_msg_content_equals("Wrong field type: expected string, got cdata", function()
+        key_def.new({{field = 1, type = box.NULL}})
+    end)
+    t.assert_error_msg_content_equals("Wrong field type: expected string, got table", function()
+        key_def.new({{field = 1, type = {}}})
+    end)
+    t.assert_error_msg_content_equals("Wrong field type: expected string, got boolean", function()
+        key_def.new({{field = 1, type = true}})
+    end)
+    t.assert_error_msg_content_equals("Unknown field type: 2989", function()
+        key_def.new({{field = 1, type = 2989}})
+    end)
+    t.assert_error_msg_content_equals("Unknown field type: bad", function()
+        key_def.new({{field = 1, type = 'bad'}})
+    end)
+    t.assert_error_msg_content_equals("Unknown field type: ", function()
+        key_def.new({{field = 1, type = ''}})
+    end)
+end