diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 4fbdc62d8c..df5f219254 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -644,6 +644,10 @@ ResetCatalogCache(CatCache *cache)
 	dlist_mutable_iter iter;
 	int			i;
 
+	/* If the cache is entirely empty, there's nothing to do */
+	if (cache->cc_ntup == 0)
+		return;
+
 	/* Remove each list in this cache, or at least mark it dead */
 	dlist_foreach_modify(iter, &cache->cc_lists)
 	{
diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c
index 6546e3c7c7..1ac87725c0 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -1455,11 +1455,23 @@ hash_seq_search(HASH_SEQ_STATUS *status)
 	}
 
 	/*
-	 * Search for next nonempty bucket starting at curBucket.
+	 * Nothing to do if hash table is entirely empty.  (For a partitioned
+	 * hash table, we'd have to check all the freelists, which is unlikely
+	 * to be a win.)
 	 */
-	curBucket = status->curBucket;
 	hashp = status->hashp;
 	hctl = hashp->hctl;
+	if (hctl->freeList[0].nentries == 0 &&
+		!IS_PARTITIONED(hctl))
+	{
+		hash_seq_term(status);
+		return NULL;			/* table is empty */
+	}
+
+	/*
+	 * Search for next nonempty bucket starting at curBucket.
+	 */
+	curBucket = status->curBucket;
 	ssize = hashp->ssize;
 	max_bucket = hctl->max_bucket;
 
