diff --git a/src/box/key_def.c b/src/box/key_def.c
index bdd6561d5edf61c3831f1d699b1e0d9c72c0d19f..8097cf303665cf1f5309ccda0836a5a0db7826ac 100644
--- a/src/box/key_def.c
+++ b/src/box/key_def.c
@@ -1016,10 +1016,12 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count,
 const struct key_part *
 key_def_find_by_fieldno(const struct key_def *key_def, uint32_t fieldno)
 {
-	struct key_part part;
-	memset(&part, 0, sizeof(struct key_part));
-	part.fieldno = fieldno;
-	return key_def_find(key_def, &part);
+	const struct key_part *part = key_def->parts;
+	const struct key_part *end = part + key_def->part_count;
+	for (; part != end; part++)
+		if (part->fieldno == fieldno)
+			return part;
+	return NULL;
 }
 
 const struct key_part *
diff --git a/src/box/key_def.h b/src/box/key_def.h
index 4d90a0a0004deb03a89ad3c67347301700460b71..11703995420708a8c79ba7853d0b550b3d245f0c 100644
--- a/src/box/key_def.h
+++ b/src/box/key_def.h
@@ -730,7 +730,9 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count,
 		     uint32_t field_count, struct region *region);
 
 /**
- * Returns the part in index_def->parts for the specified fieldno.
+ * Returns the first part in index_def->parts for the specified fieldno.
+ * The part is returned regardless of whether it is indexed by JSON path or not.
+ *
  * If fieldno is not in index_def->parts returns NULL.
  */
 const struct key_part *
diff --git a/test/unit/key_def.cc b/test/unit/key_def.cc
index 7f1d4fc96e3b6b3ba1d065181f3075fa2f5d45d5..e96c2b99468de97bb6c1c09346d67a82f47ee2fa 100644
--- a/test/unit/key_def.cc
+++ b/test/unit/key_def.cc
@@ -1367,10 +1367,38 @@ test_tuple_compare_sequential_no_optional_parts_unique(bool ascending_key,
 	check_plan();
 }
 
+static void
+test_key_def_find_by_fieldno(void)
+{
+	plan(3);
+	header();
+
+	const struct key_part *key_part;
+	struct key_def *key_def = test_key_def_new(
+		"[{%s%u%s%s}{%s%u%s%s}{%s%u%s%s%s%s}]",
+		"field", 1, "type", "unsigned",
+		"field", 2, "type", "string",
+		"field", 3, "type", "string", "path", "foo");
+
+	key_part = key_def_find_by_fieldno(key_def, 2);
+	isnt(key_part, NULL, "field 2 (no path) found");
+
+	key_part = key_def_find_by_fieldno(key_def, 3);
+	isnt(key_part, NULL, "field 3 (with path) found");
+
+	key_part = key_def_find_by_fieldno(key_def, 100);
+	is(key_part, NULL, "field 100 not found");
+
+	key_def_delete(key_def);
+
+	footer();
+	check_plan();
+}
+
 static int
 test_main(void)
 {
-	plan(50);
+	plan(51);
 	header();
 
 	test_func_compare();
@@ -1423,6 +1451,7 @@ test_main(void)
 	test_key_compare_singlepart(true, false);
 	test_key_compare_singlepart(false, true);
 	test_key_compare_singlepart(false, false);
+	test_key_def_find_by_fieldno();
 
 	footer();
 	return check_plan();