diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 377d0842bdd9d0f77588ba58b4fdeb4bc00f6922..1933a87d6568e68a6a7466ee442f95c16bb549b8 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -173,6 +173,8 @@
 #define MULTIXACT_MEMBER_DANGER_THRESHOLD	\
 	(MaxMultiXactOffset - MaxMultiXactOffset / 4)
 
+#define PreviousMultiXactId(xid) \
+	((xid) == FirstMultiXactId ? MaxMultiXactId : (xid) - 1)
 
 /*
  * Links to shared-memory data structures for MultiXact control
@@ -3057,10 +3059,15 @@ TruncateMultiXact(void)
 
 	SlruScanDirectory(MultiXactMemberCtl, SlruScanDirCbRemoveMembers, &range);
 
-	/* Now we can truncate MultiXactOffset */
+	/*
+	 * Now we can truncate MultiXactOffset.  We step back one multixact to
+	 * avoid passing a cutoff page that hasn't been created yet in the rare
+	 * case that oldestMXact would be the first item on a page and oldestMXact
+	 * == nextMXact.  In that case, if we didn't subtract one, we'd trigger
+	 * SimpleLruTruncate's wraparound detection.
+	 */
 	SimpleLruTruncate(MultiXactOffsetCtl,
-					  MultiXactIdToOffsetPage(oldestMXact));
-
+				  MultiXactIdToOffsetPage(PreviousMultiXactId(oldestMXact)));
 
 	/*
 	 * Now, and only now, we can advance the stop point for multixact members.
diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c
index 4bc24d9bbcbc4fbdb9660f237d730d6f77432b27..6b709823227803b6975c5a962e2dced57a8e0f97 100644
--- a/src/backend/access/transam/subtrans.c
+++ b/src/backend/access/transam/subtrans.c
@@ -340,8 +340,13 @@ TruncateSUBTRANS(TransactionId oldestXact)
 
 	/*
 	 * The cutoff point is the start of the segment containing oldestXact. We
-	 * pass the *page* containing oldestXact to SimpleLruTruncate.
+	 * pass the *page* containing oldestXact to SimpleLruTruncate.  We step
+	 * back one transaction to avoid passing a cutoff page that hasn't been
+	 * created yet in the rare case that oldestXact would be the first item on
+	 * a page and oldestXact == next XID.  In that case, if we didn't subtract
+	 * one, we'd trigger SimpleLruTruncate's wraparound detection.
 	 */
+	TransactionIdRetreat(oldestXact);
 	cutoffPage = TransactionIdToPage(oldestXact);
 
 	SimpleLruTruncate(SubTransCtl, cutoffPage);