Microsoft 365

Fix TooManyBadItemsPermanentException in Exchange Online mailbox moves

Find out why a mailbox move fails with TooManyBadItemsPermanentException, read the bad items in the move report, and complete it with skipped-item approval or a permissions cleanup.

11 min read
On this page

TooManyBadItemsPermanentException means a mailbox move hit more bad items than it was allowed to skip, so the Mailbox Replication service stopped the move. In hybrid moves to Exchange Online, the bad items are usually mailbox or folder permissions that point to a user or group that can't be resolved, not damaged messages. Read the bad items from the move report, fix or remove the unresolvable permissions and resubmit the move, or, where the item loss is acceptable, review and approve the skipped items so the Data Consistency Score lets the migration complete.

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

This guide is for Exchange administrators moving mailboxes between Exchange Server and Exchange Online with remote move migrations, typically in a hybrid deployment. Microsoft notes that the same guidance may also apply to the closely related TooManyMissingItemsPermanentException, because missing items are counted in the bad item limit.

By the end you will have:

  • The move report for the failed user and a list of its bad items, grouped by kind.
  • A clear decision for each mailbox: fix permissions and resubmit, repair the source, or approve the skipped items.
  • A completed move and a check that nothing important was left behind.

For the bigger picture of planning moves between organizations, see the cross-tenant migration architecture post.

What counts as a bad item

The cmdlet reference defines a bad item as a corrupt item in the source mailbox that can't be copied to the target mailbox. Missing items are counted too: items in the source that can't be found in the target when the request is ready to complete.

Permissions joined that list in 2016. A move runs in stages: it creates the folder hierarchy, copies the data (the initial sync), and then copies rules and security descriptors. Security descriptors are the access control lists on the mailbox and on each folder. About midway through 2016, Exchange Online started marking a security principal that it couldn't validate or map to an Exchange Online object as a bad item. Before that, invalid permissions were silently dropped. Every unresolvable entry now increments the bad item count, so a mailbox with years of permissions for departed staff can fail even though every message copied cleanly.

Only explicit mailbox permissions are copied, such as Full Access granted with Add-MailboxPermission. Inherited permissions, for example a Receive-As grant on a database, aren't evaluated.

To resolve a permission, Exchange Online sends the SID to the on-premises MRSProxy, which looks it up in Active Directory and returns attributes including the legacyExchangeDN. Exchange Online then looks for a cloud recipient with that value stamped as an X500 proxy address. If any step fails, the entry becomes a bad item. The move report records it as one of two kinds:

Report entryMeaningTypical cause
Unable to translate principals ... Failed to find a principal from the source forest (SourcePrincipalMapping)The SID couldn't be resolved in on-premises Active Directory.The user was deleted, or the SID exists only in SIDHistory, which MRSProxy doesn't search.
Failed to find a principal in the target forest that corresponds to the following source forest principal values (TargetPrincipalMapping)The principal exists on-premises but has no matching object in Exchange Online.The user or group is outside the directory synchronization scope, or it's a security group that isn't mail-enabled, which isn't synchronized to Exchange Online.

Exchange Online has a separate built-in bad item limit of 1,000 for source principal mapping errors, so those alone fail a move only when there are more than 1,000 of them. A move that fails on permissions therefore points either to a very large number of stale entries or to target mapping errors.

BadItemLimit versus the Data Consistency Score

Older guidance, including the Microsoft support article for this error, tells you to raise BadItemLimit on the move request and resume it. Check which environment you're in before you follow that:

Where the move request livesHow bad items are handled
Exchange Online (hybrid onboarding and offboarding batches, move requests created in Exchange Online PowerShell)The cmdlet reference lists BadItemLimit and LargeItemLimit as available only in on-premises Exchange and deprecated in the cloud-based service. Admins review the Data Consistency Score and approve skipped items before the migration completes.
On-premises Exchange Server (local moves between databases)BadItemLimit is still a valid parameter. The default is 0; Microsoft recommends 10 or lower if you accept leaving a few items behind.

The Data Consistency Score has four grades:

GradeMeaningApproval
PerfectNo inconsistencies.Not required.
GoodAt least one inconsistency, but not impactful, such as lost metadata or folder permissions.Not required.
InvestigateA small amount of noticeable data loss.Required for remote move, public folder and Google Workspace migrations.
PoorMajor data loss.Contact Microsoft Support. Approval can't force completion.

A batch's score equals the worst score of any user in it. A migration user held back for this reason reports an error such as The data consistency score (Investigate) for this request is too low.

Prerequisites

  • Exchange Online PowerShell with permissions to manage migrations:
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
  • Exchange Management Shell access on-premises, to change permissions and run repairs on the source mailbox.
  • The identity of the failed user. The examples use ana@contoso.com and a batch named Batch-Finance.

Step 1: Find the failed user and capture the move report

List failed users and their errors:

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

Then save the full move report. Working from a saved copy lets you analyze it in a plain PowerShell window without a live connection, and it's the file Microsoft Support asks for:

Get-MoveRequestStatistics -Identity ana@contoso.com -IncludeReport |
    Export-Clixml C:\Temp\ana-movereport.xml
 
$movereport = Import-Clixml C:\Temp\ana-movereport.xml

If the move request was already removed but the mailbox exists, the support article for this error reads the report from the mailbox's move history instead:

$stats = Get-MailboxStatistics ana@contoso.com -IncludeMoveReport
$report = $stats.MoveHistory[0].Report
$report.BadItems

Step 2: Classify the bad items

List the bad items and open them in a grid you can filter:

$movereport.Report.BadItems | Out-GridView

In the grid, select Add criteria, choose Kind, set the condition to does not contain and type Security. If the list is now empty, every bad item is a permissions problem and no message content is at risk. If entries remain, you also have corrupt, large or missing items.

To check the overall failure pattern in the same report:

$movereport.Report.Failures | Group-Object FailureType | Format-Table -AutoSize
$movereport.Report.Failures[-1]

For skipped items at the migration-user level, including the scoring classification for each one:

$userStats = Get-MigrationUserStatistics -Identity ana@contoso.com -IncludeSkippedItems
$userStats.SkippedItems | Format-Table -AutoSize Subject, Sender, DateSent, ScoringClassifications

The same list is in the Exchange admin center: go to Migration, select the batch, select View details, select the user, and then select Skipped item details.

Step 3: Apply the fix that matches the bad items

Permissions: fix them on-premises and submit a new move

The Exchange Team's recommended approach is to keep bad item tolerance low and remediate the mailboxes that fail, because a failure means either a very large number of stale permissions or valid permissions that aren't mapping to Exchange Online. Both deserve a look.

  1. From the report entries, note the SIDs, aliases or display names that couldn't be translated, and the folder names for folder-level entries.
  2. On-premises, review the mailbox and folder permissions with Get-MailboxPermission and Get-MailboxFolderPermission.
  3. For source mapping errors (deleted accounts), remove the stale entries with Remove-MailboxPermission or Remove-MailboxFolderPermission.
  4. For target mapping errors, decide whether the principal should exist in Exchange Online. If a user is outside the synchronization scope, bring it into scope. If permissions were granted to a security group that isn't mail-enabled, remember that such groups aren't synchronized to Exchange Online; grant the access to a principal that is synchronized, or remove the entry.
  5. Remove the failed move and submit a new one.

The last step matters. Permissions are evaluated only once, at the end of the initial data copy. Fixing them while the failed move request still exists doesn't help that request; you have to remove it and start again:

Remove-MigrationUser -Identity ana@contoso.com

Then add the user to a new batch, or, for a single mailbox, create a new remote move request from Exchange Online PowerShell.

Corrupt items: repair or relocate the source mailbox

When the remaining bad items aren't permissions, try to clean the source first. Microsoft's hybrid troubleshooter notes that corrupt items or mailboxes can often be fixed by moving the mailbox between two on-premises mailbox databases before moving it to Exchange Online. On Exchange Server, New-MailboxRepairRequest can also detect and repair some mailbox corruption:

New-MailboxRepairRequest -Mailbox ana@contoso.com -CorruptionType MessageId
Get-MailboxRepairRequest -Mailbox ana@contoso.com

Run these in the Exchange Management Shell on-premises; they aren't available in Exchange Online.

Accept the loss: approve skipped items

If you have reviewed the skipped items and the loss is acceptable, approve them so the migration can complete. For a migration user or a whole batch:

Set-MigrationUser -Identity ana@contoso.com -ApproveSkippedItems
Set-MigrationBatch -Identity Batch-Finance -ApproveSkippedItems

ApproveSkippedItems marks all skipped items discovered before the current time as approved. For a move request you manage directly, use the approval time instead:

Set-MoveRequest -Identity ana@contoso.com -SkippedItemApprovalTime $(Get-Date).ToUniversalTime()

Approving a batch scored Investigate lets every user scored Perfect, Good or Investigate complete. In a batch scored Poor, approval still completes those users but never a user scored Poor. Those need Microsoft Support.

For Google Workspace migrations, where both mailboxes stay live, new skipped items can appear after you approve, so you may need to approve more than once.

On-premises local moves: raise BadItemLimit

For a move request in on-premises Exchange Server, the classic fix still applies. Keep the number as low as the report justifies:

Set-MoveRequest -Identity ana@contoso.com -BadItemLimit 10
Resume-MoveRequest -Identity ana@contoso.com

In Exchange Server 2010, values of 51 or higher also require -AcceptLargeDataLoss.

Verification

Get-MigrationUser -Identity ana@contoso.com | Format-List Status, DataConsistencyScore
Get-MigrationUserStatistics -Identity ana@contoso.com | Format-List SkippedItemCount, SkippedItems
Get-MigrationBatch -Identity Batch-Finance | Format-List Status, DataConsistencyScore

You want the user to reach Synced or Completed, the score to be Perfect, Good or an approved Investigate, and the skipped item count to match what you reviewed. After completion, ask delegates of the migrated mailbox to confirm that shared folder access still works; permissions that were dropped as bad items have to be re-granted in Exchange Online.

If the batch was set to complete automatically but stays incomplete, a low Data Consistency Score is a common reason. Approve the skipped items and complete the batch.

Troubleshooting

SymptomCauseFix
TooManyBadItemsPermanentException, report full of Unable to translate principalsUnresolvable mailbox or folder permissionsClean up permissions on-premises, remove the migration user, submit a new move.
Same error after fixing permissions and resumingPermissions are evaluated once per moveRemove the move and create a new one.
TooManyMissingItemsPermanentExceptionItems missing from the target at completion count as bad itemsReview skipped items; approve if acceptable.
The data consistency score (Investigate) for this request is too lowSkipped items need approvalReview, then Set-MigrationUser -ApproveSkippedItems.
Grade PoorMajor data loss detectedContact Microsoft Support; approval doesn't apply.
Older guidance says to raise -BadItemLimit on an Exchange Online moveThe parameter is documented as deprecated in the cloud serviceUse skipped-item review and approval instead.
Bad items that aren't permissionsItem-level corruption in the sourceMove between on-premises databases or run New-MailboxRepairRequest, then retry.

Microsoft documents a MoveOptions parameter on New-MoveRequest for skipping move stages such as folder ACLs, but its reference says not to use it unless Microsoft Support or specific documentation directs you to.

Checklist

  • Save the move report with Export-Clixml before changing anything.
  • Group bad items by Kind; separate permissions from content.
  • Permissions: remove stale entries, fix sync scope, avoid non-mail-enabled security groups, then resubmit the move.
  • Content: relocate or repair the source mailbox, then retry.
  • Review skipped items and approve only what you accept losing.
  • Escalate a Poor grade to Microsoft Support.
  • After completion, re-grant any permissions that were dropped.

References

Questions people ask

What causes TooManyBadItemsPermanentException?

The move found more bad items than the request allows. Bad items are corrupt items that can't be copied, items missing from the target at completion, and, since a 2016 change in Exchange Online, mailbox and folder permissions whose security principal can't be mapped to an Exchange Online object.

Can I still raise BadItemLimit in Exchange Online?

The cmdlet reference for New-MigrationBatch, Set-MigrationBatch and Set-MoveRequest marks BadItemLimit and LargeItemLimit as deprecated in the cloud-based service. Exchange Online uses the Data Consistency Score instead, and you review and approve skipped items before the migration completes.

Will fixing the permissions let the failed move resume?

No. Permissions are evaluated once, at the end of the initial data copy. If a move failed on bad permissions, fixing them doesn't change the outcome of that move; remove the move request, fix the permissions and submit a new move.

What does a Data Consistency Score of Poor mean?

Poor means major data loss was detected. You can't force a migration with a Poor grade to complete by approving skipped items; Microsoft's guidance is to contact Microsoft Support.

Exchange OnlineMailbox movesData consistency scoreExchange Online PowerShell
  1. 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
  2. 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
  3. EWS retirement in Exchange Online: find EWS apps and set EWSAllowedAppIDs

    Find every app that still calls Exchange Web Services, build an EWSAllowedAppIDs allow list and set EWSEnabled so critical apps keep working while EWS is switched off from October 2026.

    Microsoft 36513 min read