diff --git a/migration/file.c b/migration/file.c
index ab18ba505a1d..34dfbc4a5a2d 100644
--- a/migration/file.c
+++ b/migration/file.c
@@ -62,7 +62,10 @@ bool file_send_channel_create(gpointer opaque, Error **errp)
         goto out;
     }
 
-    multifd_channel_connect(opaque, QIO_CHANNEL(ioc));
+    ret = multifd_channel_connect(opaque, QIO_CHANNEL(ioc), errp);
+    if (!ret) {
+        object_unref(OBJECT(ioc));
+    }
 
 out:
     /*
diff --git a/migration/multifd.c b/migration/multifd.c
index 4bc912d7500e..58a18bb1e4a8 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1010,34 +1010,76 @@ out:
     return NULL;
 }
 
-static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque);
-
-typedef struct {
+struct MFDSendChannelConnectData {
+    unsigned int ref;
     MultiFDSendParams *p;
     QIOChannelTLS *tioc;
-} MultiFDTLSThreadArgs;
+};
+
+static MFDSendChannelConnectData *mfd_send_channel_connect_data_new(MultiFDSendParams *p)
+{
+    MFDSendChannelConnectData *data;
+
+    data = g_malloc0(sizeof(*data));
+    data->ref = 1;
+    data->p = p;
+
+    return data;
+}
+
+static void mfd_send_channel_connect_data_free(MFDSendChannelConnectData *data)
+{
+    g_free(data);
+}
+
+static MFDSendChannelConnectData *
+mfd_send_channel_connect_data_ref(MFDSendChannelConnectData *data)
+{
+    unsigned int ref_old;
+
+    ref_old = qatomic_fetch_inc(&data->ref);
+    assert(ref_old < UINT_MAX);
+
+    return data;
+}
+
+static void mfd_send_channel_connect_data_unref(gpointer opaque)
+{
+    MFDSendChannelConnectData *data = opaque;
+    unsigned int ref_old;
+
+    ref_old = qatomic_fetch_dec(&data->ref);
+    assert(ref_old > 0);
+    if (ref_old == 1) {
+        mfd_send_channel_connect_data_free(data);
+    }
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(MFDSendChannelConnectData, mfd_send_channel_connect_data_unref)
+
+static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque);
 
 static void *multifd_tls_handshake_thread(void *opaque)
 {
-    MultiFDTLSThreadArgs *args = opaque;
+    g_autoptr(MFDSendChannelConnectData) data = opaque;
+    QIOChannelTLS *tioc = data->tioc;
 
-    qio_channel_tls_handshake(args->tioc,
+    qio_channel_tls_handshake(tioc,
                               multifd_new_send_channel_async,
-                              args->p,
-                              NULL,
+                              g_steal_pointer(&data),
+                              mfd_send_channel_connect_data_unref,
                               NULL);
-    g_free(args);
 
     return NULL;
 }
 
-static bool multifd_tls_channel_connect(MultiFDSendParams *p,
+static bool multifd_tls_channel_connect(MFDSendChannelConnectData *data,
                                         QIOChannel *ioc,
                                         Error **errp)
 {
+    MultiFDSendParams *p = data->p;
     MigrationState *s = migrate_get_current();
     const char *hostname = s->hostname;
-    MultiFDTLSThreadArgs *args;
     QIOChannelTLS *tioc;
 
     tioc = migration_tls_client_create(ioc, hostname, errp);
@@ -1053,19 +1095,21 @@ static bool multifd_tls_channel_connect(MultiFDSendParams *p,
     trace_multifd_tls_outgoing_handshake_start(ioc, tioc, hostname);
     qio_channel_set_name(QIO_CHANNEL(tioc), "multifd-tls-outgoing");
 
-    args = g_new0(MultiFDTLSThreadArgs, 1);
-    args->tioc = tioc;
-    args->p = p;
+    data->tioc = tioc;
 
     p->tls_thread_created = true;
     qemu_thread_create(&p->tls_thread, "multifd-tls-handshake-worker",
-                       multifd_tls_handshake_thread, args,
+                       multifd_tls_handshake_thread,
+                       mfd_send_channel_connect_data_ref(data),
                        QEMU_THREAD_JOINABLE);
     return true;
 }
 
-void multifd_channel_connect(MultiFDSendParams *p, QIOChannel *ioc)
+bool multifd_channel_connect(MFDSendChannelConnectData *data, QIOChannel *ioc,
+                             Error **errp)
 {
+    MultiFDSendParams *p = data->p;
+
     qio_channel_set_delay(ioc, false);
 
     migration_ioc_register_yank(ioc);
@@ -1075,6 +1119,8 @@ void multifd_channel_connect(MultiFDSendParams *p, QIOChannel *ioc)
     p->thread_created = true;
     qemu_thread_create(&p->thread, p->name, multifd_send_thread, p,
                        QEMU_THREAD_JOINABLE);
+
+    return true;
 }
 
 /*
@@ -1085,7 +1131,8 @@ void multifd_channel_connect(MultiFDSendParams *p, QIOChannel *ioc)
  */
 static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
 {
-    MultiFDSendParams *p = opaque;
+    MFDSendChannelConnectData *data = opaque;
+    MultiFDSendParams *p = data->p;
     QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));
     Error *local_err = NULL;
     bool ret;
@@ -1101,13 +1148,12 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
                                        migrate_get_current()->hostname);
 
     if (migrate_channel_requires_tls_upgrade(ioc)) {
-        ret = multifd_tls_channel_connect(p, ioc, &local_err);
+        ret = multifd_tls_channel_connect(data, ioc, &local_err);
         if (ret) {
             return;
         }
     } else {
-        multifd_channel_connect(p, ioc);
-        ret = true;
+        ret = multifd_channel_connect(data, ioc, &local_err);
     }
 
 out:
@@ -1134,11 +1180,16 @@ out:
 
 static bool multifd_new_send_channel_create(MultiFDSendParams *p, Error **errp)
 {
+    g_autoptr(MFDSendChannelConnectData) data = NULL;
+
+    data = mfd_send_channel_connect_data_new(p);
+
     if (!multifd_use_packets()) {
-        return file_send_channel_create(p, errp);
+        return file_send_channel_create(data, errp);
     }
 
-    socket_send_channel_create(multifd_new_send_channel_async, p, NULL);
+    socket_send_channel_create(multifd_new_send_channel_async, g_steal_pointer(&data),
+                               mfd_send_channel_connect_data_unref);
     return true;
 }
 
diff --git a/migration/multifd.h b/migration/multifd.h
index c9d9b0923953..fd0cd29104c1 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -250,6 +250,8 @@ static inline void multifd_send_prepare_header(MultiFDSendParams *p)
     p->iovs_num++;
 }
 
-void multifd_channel_connect(MultiFDSendParams *p, QIOChannel *ioc);
+struct MFDSendChannelConnectData;
+typedef struct MFDSendChannelConnectData MFDSendChannelConnectData;
+bool multifd_channel_connect(MFDSendChannelConnectData *data, QIOChannel *ioc, Error **errp);
 
 #endif
