Checklist
Stalled mailbox move checklist
Based on the article: StalledDueToTarget_MdbReplication and failed moves: fixing stuck Exchange mailbox moves · 5 min read
You start moving mailboxes between databases and, hours later, most of them still sit at a low percentage with a StalledDueToTarget_* status, or a few have flipped to Failed. In this post I'll show how to read StatusDetail and the Mailbox Replication service (MRS) report, how to tell normal workload-management throttling from a real problem, and how to fix and resume stalled or failed moves on Exchange Server SE and Exchange 2019.
Symptoms to confirm
- Start with an overview of every request:
Get-MoveRequest -ResultSize Unlimited | Get-MoveRequestStatistics |
Sort-Object StatusDetail | Format-Table DisplayName, StatusDetail, PercentComplete, TotalMailboxSize -AutoSize- Stalled requests show one of these values in
StatusDetail:
StalledDueToTarget_MdbReplication
StalledDueToTarget_MdbAvailability
StalledDueToTarget_DiskLatency- The MRS report of a stalled request (
-IncludeReport) contains lines such as:
Relinquishing job because of large delays due to unfavorable server health or budget limitations with a request throttling state 'StalledDueToTarget_MdbAvailability'.- A failed request shows
StatusasFailed,FailureTypeasTooManyBadItemsPermanentExceptionand a message like this:
Error: This mailbox exceeded the maximum number of corrupted items that were specified for this move request.Likely causes
- Workload management protects the servers. Before MRS writes more data, workload management (WLM) checks resources on the source and target: replication to the passive DAG copies (MdbReplication), database availability (MdbAvailability), disk latency and content-index freshness. When one of them is unhealthy the move pauses; if the delay drags on, MRS "relinquishes" the job and picks it up again later. A stall is not a failure. Microsoft's reference for
Get-MoveRequestStatisticsnotes that many messages are temporary and that a request whose status isQueuedorInProgressis still progressing normally. - Concurrency limits by design. Microsoft documents that WLM in Exchange Server 2019 allows 10 simultaneous moves from the same source or to the same target by default. In a batch of 50 mailboxes going to one database, about 10 show
CopyingMessagesand the rest show stalled states until a slot frees up. - A genuinely unhealthy target. If only a handful of moves run and they stay stalled, look for a passive copy with a growing queue, a failed or suspended copy, a database that keeps failing over, or slow storage.
- Data problems. A new move request allows zero bad items by default, so a single corrupted item can fail it. Items larger than the target allows count against
LargeItemLimitin the same way. - Locks and service problems. A mailbox left locked by an earlier move, or an MRS instance that has stopped processing.
Checklist
- 1
Read the request in detail
The statistics and the last report lines tell you what MRS is waiting for.
powershell$s = Get-MoveRequestStatistics -Identity alex@contoso.com -IncludeReport $s | Format-List Status, StatusDetail, PercentComplete, SourceDatabase, TargetDatabase, BadItemsEncountered, FailureType, Message $s.Report.Entries | Select-Object -Last 30 $s | Export-Clixml C:\Temp\alex-move.xml # keep a copy for later analysis - 2
Count the moves per target database
powershellGet-MoveRequest -MoveStatus InProgress | Get-MoveRequestStatistics | Group-Object TargetDatabase | Format-Table Name, Count -AutoSizeIf ten or more are heading for one database, the stalls are throttling. Wait, spread the batch across more target databases, or raise the WLM limits with the
New-SettingOverridecommands in Microsoft's article (see References), and only if the servers have CPU, disk and network headroom. - 3
Fix replication on the target (MdbReplication)
powershellGet-MailboxDatabaseCopyStatus DB02\* | Format-Table Name, Status, CopyQueueLength, ReplayQueueLength, ContentIndexState -AutoSize Test-ReplicationHealth -Identity EX02Good looks like every copy
Healthy, queues near zero and every testPassed. Resume or reseed broken copies first; moves generate transaction logs quickly, so the replication network has to keep up. - 4
Check availability and storage (MdbAvailability, DiskLatency)
Confirm the target is mounted and not bouncing between DAG members with
Get-MailboxDatabase DB02 -Status | Format-List Name, Mounted, MountedOnServer, then check latency on the database and log volumes. Keep moves out of backup windows and other heavy I/O jobs. - 5
Handle bad items, then resume a failed move
powershell$s.Report.BadItems | Select-Object -First 20 Set-MoveRequest -Identity alex@contoso.com -BadItemLimit 20 Resume-MoveRequest -Identity alex@contoso.comValues of 51 or more also need
-AcceptLargeDataLoss; use-LargeItemLimitthe same way for oversized items. Every skipped item is lost for good, so keep the limit as low as works. - 6
Locked mailboxes and MRS itself
Check the service on the server named in
MRSServerNamewithTest-MRSHealth -Identity EX02. RestartingMSExchangeMailboxReplicationthere interrupts the moves it is processing, which then resume. - 7
Last resort: start again
Remove-MoveRequest -Identity alex@contoso.comdiscards the partial copy. The source mailbox stays in place until a move completes, so you can safely create a new request afterwards.
Verify
- Good looks like
StatusDetailmoving throughCopyingMessagestoCompleted, and the mailbox'sDatabaseshowing the target. CompletedWithWarningmeans something was skipped or not cleaned up, so read the report before you accept it.- Then clear finished requests, because a mailbox that still has a request attached can't be moved again:
Get-MoveRequest -ResultSize Unlimited | Get-MoveRequestStatistics |
Format-Table DisplayName, Status, StatusDetail, PercentComplete -AutoSize
Get-Mailbox alex@contoso.com | Format-List DatabaseGet-MoveRequest -MoveStatus Completed | Remove-MoveRequest -Confirm:$falsePrevent it next time
- Check DAG health (copy status, queues, content index) before every large batch, and keep watching it while the batch runs.
- Spread big batches across several target databases, run them outside business hours, and use
-SuspendWhenReadyToCompleteonNew-MoveRequestto control the final switch. - Size log volumes and backups for the transaction logs that moves generate on the target.
- Moved mailboxes stay soft-deleted in the source database for the retention period; see Reclaiming Exchange database white space for what that means for disk space.
- Treat
BadItemLimitas a data-loss decision, never as a large default you set on every request.