diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index e8e5379672..efccafc4d2 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -3430,26 +3430,26 @@ virDomainMigrateVersion3Full(virDomainPtr domain,
         if (ddomain) {
             VIR_ERROR(_("finish step ignored that migration was cancelled"));
         } else {
-            /* If Finish reported a useful error, use it instead of the
-             * original "migration unexpectedly failed" error.
+            virErrorPtr err = virGetLastError();
+            /* When both Confirm and Finish reported an error in QEMU driver,
+             * we don't really know which error is the root cause. Let's report
+             * both errors to the user.
              *
              * This is ugly but we can't do better with the APIs we have. We
              * only replace the error if Finish was called with cancelled == 1
              * and reported a real error (old libvirt would report an error
-             * from RPC instead of MIGRATE_FINISH_OK), which only happens when
-             * the domain died on destination. To further reduce a possibility
-             * of false positives we also check that Perform returned
-             * VIR_ERR_OPERATION_FAILED.
+             * from RPC instead of MIGRATE_FINISH_OK).
              */
             if (orig_err &&
                 orig_err->domain == VIR_FROM_QEMU &&
-                orig_err->code == VIR_ERR_OPERATION_FAILED) {
-                virErrorPtr err = virGetLastError();
-                if (err &&
-                    err->domain == VIR_FROM_QEMU &&
-                    err->code != VIR_ERR_MIGRATE_FINISH_OK) {
-                    g_clear_pointer(&orig_err, virFreeError);
-                }
+                orig_err->code == VIR_ERR_OPERATION_FAILED &&
+                err &&
+                err->domain == VIR_FROM_QEMU &&
+                err->code != VIR_ERR_MIGRATE_FINISH_OK) {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("migration failed. Message from the source host: %1$s. Message from the destination host: %2$s"),
+                               orig_err->message, err->message);
+                g_clear_pointer(&orig_err, virFreeError);
             }
         }
     }
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 1582a738a3..8c0e522828 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -5904,26 +5904,26 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriver *driver,
         if (ddomain) {
             VIR_ERROR(_("finish step ignored that migration was cancelled"));
         } else {
-            /* If Finish reported a useful error, use it instead of the
-             * original "migration unexpectedly failed" error.
+            virErrorPtr err = virGetLastError();
+            /* When both Confirm and Finish reported an error in QEMU driver,
+             * we don't really know which error is the root cause. Let's report
+             * both errors to the user.
              *
              * This is ugly but we can't do better with the APIs we have. We
              * only replace the error if Finish was called with cancelled == 1
              * and reported a real error (old libvirt would report an error
-             * from RPC instead of MIGRATE_FINISH_OK), which only happens when
-             * the domain died on destination. To further reduce a possibility
-             * of false positives we also check that Perform returned
-             * VIR_ERR_OPERATION_FAILED.
+             * from RPC instead of MIGRATE_FINISH_OK).
              */
             if (orig_err &&
                 orig_err->domain == VIR_FROM_QEMU &&
-                orig_err->code == VIR_ERR_OPERATION_FAILED) {
-                virErrorPtr err = virGetLastError();
-                if (err &&
-                    err->domain == VIR_FROM_QEMU &&
-                    err->code != VIR_ERR_MIGRATE_FINISH_OK) {
-                    g_clear_pointer(&orig_err, virFreeError);
-                }
+                orig_err->code == VIR_ERR_OPERATION_FAILED &&
+                err &&
+                err->domain == VIR_FROM_QEMU &&
+                err->code != VIR_ERR_MIGRATE_FINISH_OK) {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("migration failed. Message from the source host: %1$s. Message from the destination host: %2$s"),
+                               orig_err->message, err->message);
+                g_clear_pointer(&orig_err, virFreeError);
             }
         }
     }