diff --git a/src/test/isolation/expected/eval-plan-qual-index-only-scan.out b/src/test/isolation/expected/eval-plan-qual-index-only-scan.out
new file mode 100644
index 00000000000..511c51cac05
--- /dev/null
+++ b/src/test/isolation/expected/eval-plan-qual-index-only-scan.out
@@ -0,0 +1,23 @@
+Parsed test spec with 2 sessions
+
+starting permutation: change_keys update_values commit_keys check_values
+step change_keys: 
+  UPDATE epq_ios_target
+    SET k = CASE id WHEN 1 THEN 3 WHEN 2 THEN 2 ELSE NULL END;
+
+step update_values: 
+  UPDATE epq_ios_target t
+    SET v = (SELECT k + 10 FROM epq_ios_lookup
+             WHERE k = t.k AND k % 3 <> 2)
+    WHERE id >= 1;
+ <waiting ...>
+step commit_keys: COMMIT;
+step update_values: <... completed>
+step check_values: SELECT * FROM epq_ios_target ORDER BY id;
+id|k| v
+--+-+--
+ 1|3|13
+ 2|2|  
+ 3| |  
+(3 rows)
+
diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule
index bf9a2037c70..608643b0b62 100644
--- a/src/test/isolation/isolation_schedule
+++ b/src/test/isolation/isolation_schedule
@@ -44,6 +44,7 @@ test: subxid-overflow
 test: eval-plan-qual
 test: eval-plan-qual-trigger
 test: eval-plan-qual-partition-prune
+test: eval-plan-qual-index-only-scan
 test: inplace-inval
 test: intra-grant-inplace
 test: intra-grant-inplace-db
diff --git a/src/test/isolation/specs/eval-plan-qual-index-only-scan.spec b/src/test/isolation/specs/eval-plan-qual-index-only-scan.spec
new file mode 100644
index 00000000000..3b6f19863c4
--- /dev/null
+++ b/src/test/isolation/specs/eval-plan-qual-index-only-scan.spec
@@ -0,0 +1,35 @@
+# Run a correlated index-only scan in EPQ using the updated outer keys.
+# The three rows respectively need projection, fail the scan qual, and use
+# a NULL runtime key.  All are rechecked in the same EPQ state tree.
+setup
+{
+  CREATE TABLE epq_ios_target (id int PRIMARY KEY, k int, v int);
+  CREATE TABLE epq_ios_lookup (k int PRIMARY KEY);
+  INSERT INTO epq_ios_target VALUES (1, 1, 0), (2, 1, 0), (3, 1, 0);
+  -- Enough rows to choose an index-only scan without planner overrides.
+  INSERT INTO epq_ios_lookup SELECT generate_series(0, 999);
+}
+setup { VACUUM ANALYZE epq_ios_lookup; }
+
+teardown { DROP TABLE epq_ios_target, epq_ios_lookup; }
+
+session s1
+setup { BEGIN; }
+step change_keys
+{
+  UPDATE epq_ios_target
+    SET k = CASE id WHEN 1 THEN 3 WHEN 2 THEN 2 ELSE NULL END;
+}
+step commit_keys { COMMIT; }
+
+session s2
+step update_values
+{
+  UPDATE epq_ios_target t
+    SET v = (SELECT k + 10 FROM epq_ios_lookup
+             WHERE k = t.k AND k % 3 <> 2)
+    WHERE id >= 1;
+}
+step check_values { SELECT * FROM epq_ios_target ORDER BY id; }
+
+permutation change_keys update_values(commit_keys) commit_keys check_values
