diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index 38670cd447..38235134bf 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -24,6 +24,7 @@
 #include "storage/procsignal.h"
 #include "storage/shm_mq.h"
 #include "storage/spin.h"
+#include "utils/memutils.h"
 
 /*
  * This structure represents the actual queue, stored in shared memory.
@@ -674,6 +675,7 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
 		}
 	}
 	nbytes = mqh->mqh_expected_bytes;
+	Assert(nbytes <= MaxAllocSize);
 
 	if (mqh->mqh_partial_bytes == 0)
 	{
@@ -703,8 +705,13 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
 		{
 			Size		newbuflen = Max(mqh->mqh_buflen, MQH_INITIAL_BUFSIZE);
 
+			/*
+			 * Double the buffer size until the payload fits, but limit to
+			 * MaxAllocSize.
+			 */
 			while (newbuflen < nbytes)
 				newbuflen *= 2;
+			newbuflen = Min(newbuflen, MaxAllocSize);
 
 			if (mqh->mqh_buffer != NULL)
 			{
