diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 4bd37d5beb5..58656b53e5d 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -2066,7 +2066,20 @@ asyncQueueProcessPageEntries(volatile QueuePosition *current,
 				reachedStop = true;
 				break;
 			}
-			else if (TransactionIdDidCommit(qe->xid))
+
+			/*
+			 * Quick check for the case that we're not listening on any
+			 * channels, before calling TransactionIdDidCommit().  This might
+			 * be marginally faster, but perhaps more importantly, it ensures
+			 * that if there's a bad entry in the queue for some reason for
+			 * which TransactionIdDidCommit() fails, we can skip over it on
+			 * the first LISTEN in a session, and not get stuck on it
+			 * indefinitely.
+			 */
+			if (listenChannels == NIL)
+				continue;
+
+			if (TransactionIdDidCommit(qe->xid))
 			{
 				/* qe->data is the null-terminated channel name */
 				char	   *channel = qe->data;
