diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index ccc4c6966a2..623406d57e7 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -517,6 +517,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
 				otherBlock;
 	bool		unlockedTargetBuffer;
 	bool		recheckVmPins;
+	BlockNumber nblocks = InvalidBlockNumber;
 
 	len = MAXALIGN(len);		/* be conservative */
 
@@ -582,7 +583,17 @@ RelationGetBufferForTuple(Relation relation, Size len,
 		 * We have no cached target page, so ask the FSM for an initial
 		 * target.
 		 */
+		nblocks = RelationGetNumberOfBlocks(relation);
 		targetBlock = GetPageWithFreeSpace(relation, targetFreeSpace);
+		/*
+		 * Since relation extension are not wal logged, the fsm could end up
+		 * pointing to an unlogged empty segment.
+		 * Detect it, and fall back through trying the last page
+		 */
+		if (unlikely(targetBlock >= nblocks))
+		{
+			targetBlock = InvalidBlockNumber;
+		}
 	}
 
 	/*
@@ -592,7 +603,8 @@ RelationGetBufferForTuple(Relation relation, Size len,
 	 */
 	if (targetBlock == InvalidBlockNumber)
 	{
-		BlockNumber nblocks = RelationGetNumberOfBlocks(relation);
+		if (nblocks == InvalidBlockNumber)
+			nblocks = RelationGetNumberOfBlocks(relation);
 
 		if (nblocks > 0)
 			targetBlock = nblocks - 1;
@@ -761,6 +773,12 @@ loop:
 														targetBlock,
 														pageFreeSpace,
 														targetFreeSpace);
+			/* As above, if the FSM gives us a page past the end of the relation,
+			 * give up and fallback to extending the relation */
+			if (nblocks == InvalidBlockNumber)
+				nblocks = RelationGetNumberOfBlocks(relation);
+			if (targetBlock >= nblocks)
+				targetBlock = InvalidBlockNumber;
 		}
 	}
 
-- 
2.44.0
