diff --git a/src/backend/replication/logical/slotsync.c b/src/backend/replication/logical/slotsync.c
index ad3747e598c..1c1e7a4e171 100644
--- a/src/backend/replication/logical/slotsync.c
+++ b/src/backend/replication/logical/slotsync.c
@@ -181,6 +181,28 @@ typedef struct RemoteSlot
 static void slotsync_failure_callback(int code, Datum arg);
 static void update_synced_slots_inactive_since(void);
 
+static void
+free_remote_slot(RemoteSlot *remote_slot)
+{
+	if (remote_slot->name)
+		pfree(remote_slot->name);
+	if (remote_slot->plugin)
+		pfree(remote_slot->plugin);
+	if (remote_slot->database)
+		pfree(remote_slot->database);
+
+	pfree(remote_slot);
+}
+
+static void
+free_remote_slot_list(List *remote_slots)
+{
+	foreach_ptr(RemoteSlot, remote_slot, remote_slots)
+		free_remote_slot(remote_slot);
+
+	list_free(remote_slots);
+}
+
 /*
  * Update slot sync skip stats. This function requires the caller to acquire
  * the slot.
@@ -1008,7 +1030,7 @@ fetch_remote_slots(WalReceiverConn *wrconn, List *slot_names)
 			 !XLogRecPtrIsValid(remote_slot->confirmed_lsn) ||
 			 !TransactionIdIsValid(remote_slot->catalog_xmin)) &&
 			remote_slot->invalidated == RS_INVAL_NONE)
-			pfree(remote_slot);
+			free_remote_slot(remote_slot);
 		else
 			/* Create list of remote slots */
 			remote_slot_list = lappend(remote_slot_list, remote_slot);
@@ -1733,7 +1755,7 @@ ReplSlotSyncWorkerMain(const void *startup_data, size_t startup_data_len)
 
 		remote_slots = fetch_remote_slots(wrconn, NIL);
 		some_slot_updated = synchronize_slots(wrconn, remote_slots, NULL);
-		list_free_deep(remote_slots);
+		free_remote_slot_list(remote_slots);
 
 		if (started_tx)
 			CommitTransactionCommand();
@@ -2050,7 +2072,7 @@ SyncReplicationSlots(WalReceiverConn *wrconn)
 				slot_names = extract_slot_names(remote_slots);
 
 			/* Free the current remote_slots list */
-			list_free_deep(remote_slots);
+			free_remote_slot_list(remote_slots);
 
 			/* Done if all slots are persisted i.e are sync-ready */
 			if (!slot_persistence_pending)
