Microsoft 365

Exchange Online migration batch stuck on Syncing: causes and fixes

Find out why an Exchange Online migration batch sits on Syncing, read the per-user stall reasons in PowerShell, and apply the right fix for concurrency, throttling, source health or skipped items.

13 min read
On this page

A migration batch that shows Syncing for days is rarely hung as a whole. The batch status only summarizes its users, and the usual culprits are individual mailboxes that are queued behind the endpoint's concurrency limit, stalled by throttling on the source or in Exchange Online, waiting for skipped-item approval, or failed and never retried. Find the users that aren't progressing with Get-MigrationUser and Get-MigrationUserStatistics, read the stall reason in the move report, and then fix that specific cause.

Who this is for and what you will have at the end

This guide is for Exchange and Microsoft 365 administrators running native migration batches into Exchange Online: hybrid remote moves from Exchange Server, cutover and staged migrations, IMAP migrations and Google Workspace migrations. It assumes the batch was created successfully and has started, but progress has stopped or slowed to a crawl.

By the end you will have:

  • A list of the exact mailboxes holding the batch in Syncing, with their status and error.
  • The stall reason and where the time went, for move-request based migrations.
  • The fix that matches each cause, and a way to verify the batch is moving again.

If you are still planning the project, the end-to-end flow for Gmail sources is covered in the Google Workspace to Microsoft 365 migration guide, and tenant-to-tenant moves are covered in the cross-tenant migration architecture post.

What Syncing actually means

The Migration dashboard in the Exchange admin center shows one status per batch. The important ones for this problem are:

Batch statusMeaning
SyncingThe batch was started and mailboxes in it are being actively migrated. You can stop it.
SyncedThe batch finished the initial sync. For most migration types, mailboxes are then synchronized every 24 hours during incremental sync.
Synced with errorsInitial sync finished but some mailboxes failed. Successful mailboxes keep their 24-hour incremental sync.
StoppedThe batch was never started, or it was stopped after running for a while.
CompletedThe batch is complete.

At the user level there is more detail. Get-MigrationUser -Status accepts values such as Queued, Provisioning, Syncing, Synced, IncrementalSyncing, Failed, IncrementalFailed, Completing and CompletionFailed. A user in Queued is in a running batch but hasn't started, which typically happens when all the connections on the migration endpoint are in use.

So a batch stuck on Syncing means at least one user hasn't reached Synced. Your first job is to find out which ones and why.

Also be aware of the housekeeping rules: batches with a status of Synced and no administrator activity for 60 days are stopped, batches with Stopped or Failed status are removed after 90 days, and Completed batches are removed after 60 days.

Prerequisites

  • An account with the Exchange permissions needed to run the migration cmdlets in Exchange Online.
  • The Exchange Online PowerShell module. Connect with:
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
  • For hybrid moves, access to the Exchange Management Shell on the on-premises servers that host the MRSProxy endpoint, because many stalls originate there.
  • The name of the batch. The examples below use Batch-Finance.

Step 1: Find the users that are holding the batch

Start with the batch itself and then break it down per user:

Get-MigrationBatch -Identity Batch-Finance -IncludeReport | Format-List
 
Get-MigrationUser -BatchId Batch-Finance | Get-MigrationUserStatistics

The second command lists every user in the batch with its current status. Group the users into four buckets:

  1. Queued: waiting for a migration slot. This is a concurrency question (Step 3, first section).
  2. Syncing with no change in synced data between runs a few hours apart: stalled. Read the stall reason (Step 2).
  3. Failed: the user failed and the batch is still running for everyone else. Read the error and retry.
  4. Synced: done with initial sync, nothing to fix.

For any user that looks wrong, pull the detailed report:

Get-MigrationUserStatistics -Identity ana@contoso.com -IncludeReport |
    Format-List Status,Error,Report

The same detail is in the Exchange admin center. Go to Migration, select the batch, select View details under Migration details, and then select a user. The details pane shows the status, data migrated, migration rate, error, last successful sync date and a Download the report for this user link that you can hand to Microsoft Support.

Step 2: Read the stall reason and where the time went

For hybrid remote moves, every migration user has a move request, and the move request statistics record how long the move spent in each state. The Exchange Team's guidance is to capture the diagnostic information and look at the Durations section:

$stats = Get-MoveRequestStatistics -Identity ana@contoso.com -DiagnosticInfo "verbose,showtimeslots,showtimeline"
$stats.DiagnosticInfo

The Get-MoveRequestStatistics reference lists ShowTimeline, ShowTimeslot and Verbose as the values for -DiagnosticInfo in Exchange Online, and notes that the parameter is typically used at the request of Microsoft Support. Export the result if you want to analyze it offline or attach it to a support case:

Get-MoveRequestStatistics -Identity ana@contoso.com -IncludeReport -DiagnosticInfo Verbose |
    Export-Clixml C:\Temp\ana-movereport.xml

A quicker view of throttling comes from the report itself. The TargetThrottles and SourceThrottles properties show how long the move was held back by each resource:

$r = Get-MoveRequestStatistics -Identity ana@contoso.com -IncludeReport
$r.Report.TargetThrottles
$r.Report.SourceThrottles

The status detail tells you which side is stalling. In an onboarding move (on-premises to Exchange Online) the source is your on-premises environment and the target is Exchange Online:

Stall reasonSide in an onboarding moveWhat it means
StalledDueToTarget_MdbAvailabilityExchange OnlineThe replay queue of transaction logs into remote database copies is too large. Lasts until it drains.
StalledDueToTarget_MdbReplicationExchange OnlineThe copy queue of transaction logs to other DAG members is too large.
StalledDueToTarget_DiskLatencyExchange OnlineDisk latency on the target database is at a level where more I/O could affect users.
StalledDueToTarget_ProcessorExchange OnlineCPU on the target MRS servers is too high.
StalledDueToTarget_BigFunnelExchange OnlineContent indexing had a temporary interruption and is recovering.
StalledDueToSource_UnknownReasonOn-premisesThe source didn't pass a specific reason. Most often a content indexing problem on the on-premises servers.
StalledDueToSource_MailboxLockOn-premisesA transient communication error between cloud MRS and on-premises MRSProxy left the mailbox locked.
StalledDueToSource_EndpointCapacityExceededExchange Online endpoint settingsMore moves are running than the migration endpoint's concurrency allows.

Step 3: Apply the fix that matches the cause

Users stuck in Queued: raise endpoint concurrency carefully

For IMAP, cutover and staged migrations, migration-service throttling limits how many mailboxes migrate at once. The default is 20 mailboxes across all batches, and you can raise it to a maximum of 100:

Get-MigrationEndpoint -Identity OnboardingME01 | Format-List
Set-MigrationEndpoint -Identity OnboardingME01 -MaxConcurrentMigrations 40

MaxConcurrentIncrementalSyncs must be less than or equal to MaxConcurrentMigrations. After changing the endpoint, run Set-MigrationBatch -Identity Batch-Finance -Update. The Update switch triggers the migration service to reapply all of the settings from the endpoint, batch and user to the migration process.

Raise the number gradually. Microsoft's advice is to start with a small value, for example 10, and increase it while watching the source system, because a source without enough resources affects your users before it speeds up the migration.

For hybrid moves, StalledDueToSource_EndpointCapacityExceeded appears when the endpoint values are lower than the number of mailboxes you are moving at once. The tenant-level maximum for hybrid remote moves is 300 by default and is visible in Get-MigrationConfig. Microsoft Support can raise it (up to 1,000) when you publish multiple MRSProxy endpoints, but only with a business justification, because higher concurrency loads your on-premises servers.

StalledDueToTarget: wait, and know when to escalate

Exchange Online throttles discretionary workloads such as mailbox moves so that the service keeps running well for all users, and hybrid moves are stalled when resource health drops toward the throttling threshold. Seeing target stalls is normal. There are no throttling policies that you or Microsoft Support can adjust to speed up hybrid moves, and changing EWS throttling has nothing to do with MRS-based migrations.

Microsoft considers it a service problem only when a move exceeds the 90th percentile of its published duration estimates and most of the time is spent in StalledDueToTarget. For onboarding from on-premises Exchange, the published P90 is 6 days for mailboxes of 10 to 50 GB and 13 days for 50 to 100 GB. If you are past that and the Durations section shows the target side as the main consumer, open a case and attach the exported move report.

StalledDueToSource: fix the on-premises side

Source stalls are yours to fix. Look in the verbose diagnostic info for a message that names the unhealthy resource. A content indexing problem looks like The remote server is unhealthy due to 'Resource 'CiAgeOfLastNotification(...)' is unhealthy..., and a CPU problem names the Processor resource.

  • Content indexing: when the verbose diagnostic info names a CiAgeOfLastNotification resource, the content index of the named source database is unhealthy. Repair content indexing on that database before expecting the moves to speed up.
  • CPU: add CPU or more migration servers. If a server is used only for migrations, the Exchange Team documents a setting override that disables processor throttling for MRS, but don't use it on servers that also host production mailboxes.
  • Mailbox lock: transient timeouts between Exchange Online MRS and on-premises MRSProxy leave the source mailbox locked for roughly the TCP keep-alive time of the Windows Server (two hours by default). The Exchange Team's general recommendation is to lower the TCP keep-alive time to 5 minutes so moves recover faster, but that doesn't fix the timeouts themselves. Bypass load balancers, IDS and reverse proxies in front of the MRSProxy servers where you can, decrease the MaxConcurrent* values on the hybrid migration endpoint, and improve server performance and bandwidth.
  • High latency with many folders: finalization verifies content per folder, so a mailbox with thousands of folders over a high-latency link can stay locked in final sync for a long time. Check Report.SessionStatistics.SourceLatencyInfo.Average in the move report; the recommended maximum is 300 ms.

When Exchange Server 2019 is the source or the target of the moves, seeing only 10 mailboxes in CopyingMessages with the rest in stalled states such as StalledDueToTarget_MdbReplication is expected: workload management limits moves from the same source or to the same target to 10 at a time by default. Microsoft documents New-SettingOverride commands to raise the limit, starting at 25 and not going above 100.

Google Workspace and IMAP sources: the source throttles too

For Gmail and other IMAP sources, the data source often limits how much data can be extracted in a period, so throughput drops no matter what you set in Exchange Online. Raising endpoint concurrency beyond what the source accepts only produces more throttled connections. Keep batches smaller and let incremental syncs catch up.

Failed users inside a Syncing batch: retry them

Start-MigrationBatch resumes a stopped batch and retries failures in a Failed or Synced with Errors batch. In Exchange Online it can be run at any time to retry failed users within the batch:

Start-MigrationBatch -Identity Batch-Finance

If one mailbox repeatedly fails or stalls while the rest finish, remove it with Remove-MigrationUser -Identity ana@contoso.com and migrate it in a batch of its own, so it can't hold the rest of the users.

Skipped items waiting for approval

Every migration produces a Data Consistency Score. A batch's score equals the worst score of any user in it. For remote move, public folder and Google Workspace migrations, a grade of Investigate requires you to approve skipped items before the migration can complete:

Get-MigrationUserStatistics -Identity ana@contoso.com -IncludeSkippedItems |
    Select-Object -ExpandProperty SkippedItems |
    Format-Table Subject,DateReceived -AutoSize
 
Set-MigrationUser -Identity ana@contoso.com -ApproveSkippedItems
# or for every user in the batch
Set-MigrationBatch -Identity Batch-Finance -ApproveSkippedItems

A grade of Poor can't be forced through; contact Microsoft Support. Note that the BadItemLimit and LargeItemLimit parameters of Set-MigrationBatch are available only in on-premises Exchange, so in Exchange Online skipped-item approval is the mechanism, not raising a limit.

Verify that the batch is moving again

Run these checks a few hours apart:

Get-MigrationUser -BatchId Batch-Finance -Status Queued
Get-MigrationUser -BatchId Batch-Finance -Status Failed
Get-MigrationUser -BatchId Batch-Finance | Get-MigrationUserStatistics
Get-MigrationBatch -Status Syncing

You want the Queued and Failed lists to shrink, the data migrated for users still in Syncing to grow (the Data migrated and Last successful sync date fields in the EAC user details are the easiest place to see it), and the batch to reach Synced or Synced with errors. After that, incremental sync runs every 24 hours. If you need a fresh delta just before cutover, Set-MigrationBatch -Identity Batch-Finance -SyncNow starts an immediate sync for users already in Synced status (it doesn't resume Failed users).

Troubleshooting: other symptoms that look like a stuck batch

SymptomCauseFix
Batch shows Synced for weeks and never completesCompletion was never triggeredRun Complete-MigrationBatch -Identity Batch-Finance, or set -CompleteAfter.
Batch appears stuck after running Complete-MigrationBatchUnapproved skipped items, or repeated completion requests within 8 hours aren't reprocessedApprove skipped items with Set-MigrationUser -ApproveSkippedItems.
Move fails straight away with SourceMailboxAlreadyBeingMovedTransientException after you recreate itA leaked MRSProxy session still holds the source mailbox lockChanging TCP keep-alive doesn't help here. Restart the Mailbox Replication service on the on-premises server hosting the mailbox (Exchange 2013 or later).
User sees a MailboxInTransit exception in Outlook on the web during final syncThe source mailbox is locked while content verification runsExpected during finalization; complete large-folder mailboxes outside working hours.
Synced batch changed to Stopped on its ownNo administrator activity for 60 daysResume the batch and complete it.
Grade Poor on the Data Consistency ScoreMajor data loss detectedContact Microsoft Support; approval doesn't apply.

Checklist

  • Break the batch down per user before changing anything.
  • Read the stall reason and the Durations section for hybrid moves.
  • Queued users: raise MaxConcurrentMigrations in small steps and apply with Set-MigrationBatch -Update.
  • Target stalls: wait, compare against the published P90 durations, escalate with an exported report.
  • Source stalls: fix content indexing, CPU, network devices and latency on-premises.
  • Failed users: retry with Start-MigrationBatch; isolate repeat offenders in their own batch.
  • Investigate grade: review and approve skipped items before completion.
  • Complete the batch explicitly once every user is Synced.

References

Questions people ask

Why does my Exchange Online migration batch stay on Syncing for days?

The batch status is a summary. While at least one mailbox in the batch is still being copied or waiting for a free migration slot, the batch shows Syncing. Run Get-MigrationUser -BatchId with Get-MigrationUserStatistics to see which users are Queued, Syncing, Failed or Synced, and then look at the stall reason for the users that are not moving.

Is StalledDueToTarget a problem I can fix myself?

Usually not. StalledDueToTarget values such as MdbAvailability, MdbReplication, DiskLatency, Processor and BigFunnel mean Exchange Online is protecting its own resources during an onboarding move. Microsoft treats these stalls as normal unless a move exceeds the 90th percentile of its published migration duration estimates with most of the stall time on the Exchange Online side, and there are no throttling policies that tenant admins or support can adjust for hybrid moves.

Does stopping and restarting a migration batch lose data?

Stop-MigrationBatch stops mailboxes that are being actively migrated but doesn't affect mailboxes that have already been migrated. Start-MigrationBatch resumes a stopped batch and retries failed users, and in Exchange Online you can run it at any time to retry failed users in the batch.

How many mailboxes can migrate at the same time?

For IMAP, cutover and staged migrations the default is 20 concurrent mailboxes, which you can raise to a maximum of 100 with Set-MigrationEndpoint -MaxConcurrentMigrations. For hybrid remote moves the tenant-level maximum is 300 by default and is visible in Get-MigrationConfig.

Exchange OnlineMigration batchesExchange Online PowerShellExchange Hybrid
  1. Exchange hybrid remote move migration: endpoints, batches and completion

    Move mailboxes from on-premises Exchange to Exchange Online with remote move migration: enable MRS Proxy, test the endpoint, build batches, schedule completion and clean up.

    Microsoft 36512 min read
  2. Calendar permissions in Exchange Online: Add-MailboxFolderPermission guide

    Share calendars, change the organization-wide Default permission and add calendar delegates in Exchange Online with Add-, Set- and Remove-MailboxFolderPermission, including localized folder names.

    Microsoft 3659 min read
  3. Convert a user mailbox to a shared mailbox and remove the license safely

    Keep a leaver's email and calendar in Exchange Online without paying for a license: secure the account, convert the mailbox, grant access, then remove the license in the right order.

    Microsoft 36511 min read