diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 68628ec000..412c9dc318 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -224,6 +224,25 @@ search:
 			else
 				XactLockTableWait(xwait, rel, &itup->t_tid, XLTW_InsertIndex);
 
+			/*
+			 * Similar check to ExecCheckTupleVisible()
+			 */
+			if (IsolationUsesXactSnapshot() &&
+				TransactionDidCommit(xwait) &&
+				!XidInMVCCSnapshot(xwait, check_snapshot))
+			{
+				/*
+				 * We should not raise a serialization failure if the conflict is
+				 * against a tuple inserted by our own transaction, even if it's not
+				 * visible to our snapshot.  (This would happen, for example, if
+				 * conflicting keys are proposed for insertion in a single command.)
+				 */
+				if (!TransactionIdIsCurrentTransactionId(xmin))
+					ereport(ERROR,
+							(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
+							 errmsg("could not serialize access due to concurrent update")));
+			}
+
 			/* start over... */
 			if (stack)
 				_bt_freestack(stack);
