diff --git a/changelogs/unreleased/gh-8899-compare-with-key-slowpath-invalid-memory-access.md b/changelogs/unreleased/gh-8899-compare-with-key-slowpath-invalid-memory-access.md
new file mode 100644
index 0000000000000000000000000000000000000000..24a4d4a5569a7b7f2bb17b83a90c1eaadaf46da3
--- /dev/null
+++ b/changelogs/unreleased/gh-8899-compare-with-key-slowpath-invalid-memory-access.md
@@ -0,0 +1,4 @@
+## bugfix/box
+
+* Fixed the invalid memory access in a corner case of a specialized comparison
+  function (gh-8899).
diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
index 83d0cc0b1191aa4eca6d26dc1e7b29ebeb74db88..b7277518476dcc1841363e875509359c5e1d16d7 100644
--- a/src/box/tuple_compare.cc
+++ b/src/box/tuple_compare.cc
@@ -941,8 +941,9 @@ tuple_compare_with_key_sequential(struct tuple *tuple, hint_t tuple_hint,
 		cmp_part_count = part_count;
 	}
 	bool unused;
-	rc = key_compare_parts<is_nullable>(tuple_key, key, cmp_part_count,
-					    key_def, &unused);
+	rc = key_compare_and_skip_parts<is_nullable>(&tuple_key, &key,
+						     cmp_part_count,
+						     key_def, &unused);
 	if (!has_optional_parts || rc != 0)
 		return rc;
 	/*
@@ -950,11 +951,6 @@ tuple_compare_with_key_sequential(struct tuple *tuple, hint_t tuple_hint,
 	 * corresponding key fields to be equal to NULL.
 	 */
 	if (field_count < part_count) {
-		/*
-		 * Key's and tuple's first field_count fields are
-		 * equal, and their bsize too.
-		 */
-		key += tuple_bsize(tuple) - mp_sizeof_array(field_count);
 		for (uint32_t i = field_count; i < part_count;
 		     ++i, mp_next(&key)) {
 			if (mp_typeof(*key) != MP_NIL)
diff --git a/test/box-luatest/gh_8899_tuple_compare_with_key_slowpath_last_loop_test.lua b/test/box-luatest/gh_8899_tuple_compare_with_key_slowpath_last_loop_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..0d302491a12a409b0a09b13215f346b00b0be1a7
--- /dev/null
+++ b/test/box-luatest/gh_8899_tuple_compare_with_key_slowpath_last_loop_test.lua
@@ -0,0 +1,41 @@
+local server = require('luatest.server')
+local t = require('luatest')
+
+local g = t.group('gh-8899-tuple-compare-with-key-slowpath-last-loop')
+
+g.before_all(function()
+    g.server = server:new()
+    g.server:start()
+end)
+
+g.after_all(function()
+    g.server:stop()
+end)
+
+g.test_tuple_compare_with_key_slowpath_last_loop = function()
+    g.server:exec(function()
+        local ffi = require('ffi')
+
+        local function double(n)
+            return ffi.cast('double', n)
+        end
+
+        local s = box.schema.space.create('test', {engine = 'memtx'})
+        s:create_index('pk')
+        local sk = s:create_index('sk', {parts = {
+                {1, 'unsigned'},
+                {2, 'number', is_nullable = true},
+                {3, 'number', is_nullable = true}
+        }})
+
+        -- 1-byte unsigned in DB, 8-byte double in request.
+        s:replace({1, 2})
+        t.assert_equals(sk:select({1, double(2), box.NULL}, {iterator = 'EQ'}),
+                        {{1, 2}})
+
+        -- 8-byte double in DB, 1-byte unsigned in request.
+        s:replace({1, double(3)})
+        t.assert_equals(sk:select({1, 3, box.NULL}, {iterator = 'EQ'}),
+                        {{1, 3}})
+    end)
+end