diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 9366f45d74..094a44d993 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -150,8 +150,8 @@ typedef struct HeapCheckContext
 static void sanity_check_relation(Relation rel);
 static void check_tuple(HeapCheckContext *ctx);
 static void check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
-							  ToastedAttribute *ta, int32 chunkno,
-							  int32 endchunk);
+							  ToastedAttribute *ta, int32 *expected_chunk_seq,
+							  uint32 extsize);
 
 static bool check_tuple_attribute(HeapCheckContext *ctx);
 static void check_toasted_attribute(HeapCheckContext *ctx,
@@ -1163,19 +1163,19 @@ check_tuple_visibility(HeapCheckContext *ctx)
  */
 static void
 check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
-				  ToastedAttribute *ta, int32 chunkno, int32 endchunk)
+				  ToastedAttribute *ta, int32 *expected_chunk_seq,
+				  uint32 extsize)
 {
-	int32		curchunk;
+	int32		chunk_seq;
+	int32		last_chunk_seq = (extsize + 1) / TOAST_MAX_CHUNK_SIZE;
 	Pointer		chunk;
 	bool		isnull;
 	int32		chunksize;
 	int32		expected_size;
 
-	/*
-	 * Have a chunk, extract the sequence number and the data
-	 */
-	curchunk = DatumGetInt32(fastgetattr(toasttup, 2,
-										 ctx->toast_rel->rd_att, &isnull));
+	/* Sanity-check the sequence number. */
+	chunk_seq = DatumGetInt32(fastgetattr(toasttup, 2,
+										  ctx->toast_rel->rd_att, &isnull));
 	if (isnull)
 	{
 		report_toast_corruption(ctx, ta,
@@ -1183,13 +1183,25 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
 										 ta->toast_pointer.va_valueid));
 		return;
 	}
+	if (chunk_seq != *expected_chunk_seq)
+	{
+		/* Either the TOAST index is corrupt, or we don't have all chunks. */
+		report_toast_corruption(ctx, ta,
+								psprintf("toast value %u index scan returned chunk %d when expecting chunk %d",
+										 ta->toast_pointer.va_valueid,
+										 chunk_seq, *expected_chunk_seq));
+	}
+	*expected_chunk_seq = chunk_seq + 1;
+
+	/* Sanity-check the chunk data. */
 	chunk = DatumGetPointer(fastgetattr(toasttup, 3,
 										ctx->toast_rel->rd_att, &isnull));
 	if (isnull)
 	{
 		report_toast_corruption(ctx, ta,
 								psprintf("toast value %u chunk %d has null data",
-										 ta->toast_pointer.va_valueid, chunkno));
+										 ta->toast_pointer.va_valueid,
+										 chunk_seq));
 		return;
 	}
 	if (!VARATT_IS_EXTENDED(chunk))
@@ -1209,40 +1221,31 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
 		report_toast_corruption(ctx, ta,
 								psprintf("toast value %u chunk %d has invalid varlena header %0x",
 										 ta->toast_pointer.va_valueid,
-										 chunkno, header));
+										 chunk_seq, header));
 		return;
 	}
 
 	/*
 	 * Some checks on the data we've found
 	 */
-	if (curchunk != chunkno)
-	{
-		report_toast_corruption(ctx, ta,
-								psprintf("toast value %u chunk %d has sequence number %d, but expected sequence number %d",
-										 ta->toast_pointer.va_valueid,
-										 chunkno, curchunk, chunkno));
-		return;
-	}
-	if (chunkno > endchunk)
+	if (chunk_seq > last_chunk_seq)
 	{
 		report_toast_corruption(ctx, ta,
 								psprintf("toast value %u chunk %d follows last expected chunk %d",
 										 ta->toast_pointer.va_valueid,
-										 chunkno, endchunk));
+										 chunk_seq, last_chunk_seq));
 		return;
 	}
 
-	expected_size = curchunk < endchunk ? TOAST_MAX_CHUNK_SIZE
-		: VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer) - (endchunk * TOAST_MAX_CHUNK_SIZE);
+	expected_size = chunk_seq < last_chunk_seq ? TOAST_MAX_CHUNK_SIZE
+		: extsize % TOAST_MAX_CHUNK_SIZE;
 
 	if (chunksize != expected_size)
 		report_toast_corruption(ctx, ta,
 								psprintf("toast value %u chunk %d has size %u, but expected size %u",
 										 ta->toast_pointer.va_valueid,
-										 chunkno, chunksize, expected_size));
+										 chunk_seq, chunksize, expected_size));
 }
-
 /*
  * Check the current attribute as tracked in ctx, recording any corruption
  * found in ctx->tupstore.
@@ -1436,10 +1439,10 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
 	SysScanDesc toastscan;
 	bool		found_toasttup;
 	HeapTuple	toasttup;
-	int32		chunkno;
-	int32		endchunk;
+	uint32		extsize;
+	int32		expected_chunkno = 0;
 
-	endchunk = (VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer) - 1) / TOAST_MAX_CHUNK_SIZE;
+	extsize = VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer);
 
 	/*
 	 * Setup a scan key to find chunks in toast table with matching va_valueid
@@ -1458,15 +1461,13 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
 										   ctx->valid_toast_index,
 										   &SnapshotToast, 1,
 										   &toastkey);
-	chunkno = 0;
 	found_toasttup = false;
 	while ((toasttup =
 			systable_getnext_ordered(toastscan,
 									 ForwardScanDirection)) != NULL)
 	{
 		found_toasttup = true;
-		check_toast_tuple(toasttup, ctx, ta, chunkno, endchunk);
-		chunkno++;
+		check_toast_tuple(toasttup, ctx, ta, &expected_chunkno, extsize);
 	}
 	systable_endscan_ordered(toastscan);
 
@@ -1474,11 +1475,6 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
 		report_toast_corruption(ctx, ta,
 								psprintf("toast value %u not found in toast table",
 										 ta->toast_pointer.va_valueid));
-	else if (chunkno != (endchunk + 1))
-		report_toast_corruption(ctx, ta,
-								psprintf("toast value %u was expected to end at chunk %d, but ended at chunk %d",
-										 ta->toast_pointer.va_valueid,
-										 (endchunk + 1), chunkno));
 }
 
 /*
