diff --git a/changelogs/unreleased/gh-9396-ucdata-serialize-error.md b/changelogs/unreleased/gh-9396-ucdata-serialize-error.md
new file mode 100644
index 0000000000000000000000000000000000000000..43cf1d2f6e69f7b59baaf756de77c38336ac0e8a
--- /dev/null
+++ b/changelogs/unreleased/gh-9396-ucdata-serialize-error.md
@@ -0,0 +1,4 @@
+## bugfix/lua
+
+* An error from a serializer function for cdata and userdata is not ignored now
+  (gh-9396).
diff --git a/src/lua/serializer.c b/src/lua/serializer.c
index bb8952f99519e6d57ea7435d938950219c01f1c1..7c350a3ad4cd8df79fc49a9f41f06506f486d77b 100644
--- a/src/lua/serializer.c
+++ b/src/lua/serializer.c
@@ -274,7 +274,10 @@ lua_field_inspect_ucdata(struct lua_State *L, struct luaL_serializer *cfg,
 		}
 		/* copy object itself */
 		lua_pushvalue(L, idx);
-		lua_pcall(L, 1, 1, 0);
+		if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
+			diag_set(LuajitError, lua_tostring(L, -1));
+			return -1;
+		}
 		/* replace obj with the unpacked value */
 		lua_replace(L, idx);
 		if (luaL_tofield(L, cfg, idx, field) < 0)
diff --git a/test/app-luatest/gh_9396_ucdata_serialize_error_test.lua b/test/app-luatest/gh_9396_ucdata_serialize_error_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..1b3e2163784e16b8e327eab59890ae4d9eed4ab5
--- /dev/null
+++ b/test/app-luatest/gh_9396_ucdata_serialize_error_test.lua
@@ -0,0 +1,18 @@
+local t = require('luatest')
+local g = t.group()
+
+-- XXX: Use `yaml.encode()` to trigger a serialization error.
+local yaml = require('yaml')
+
+local ERRMSG = 'error in serializer'
+
+g.test_error_in_ucdata_serializer = function()
+    local ud_mt = {__serialize = function()
+        error(ERRMSG)
+    end}
+    ud_mt.__index = ud_mt
+    local ud = newproxy(true)
+    debug.setmetatable(ud, ud_mt)
+    -- XXX: This helper fails if there is no error raised.
+    t.assert_error_msg_matches('.*' .. ERRMSG, yaml.encode, ud)
+end