Exchange Server administrators dread the moment their monitoring dashboard lights up with Microsoft.Exchange.Data.Storage.TooManyObjectsOpenedException errors while Store.exe memory consumption climbs past acceptable thresholds. This error indicates that one or more processes have exceeded the maximum number of simultaneously open MAPI objects on your Exchange 2013, 2016, or 2019 server. In this article, you will learn exactly what triggers this exception, how to diagnose the root cause using PowerShell and Performance Monitor, and how to resolve it systematically before it impacts your entire messaging environment.
Prerequisites
- Exchange Server 2013, 2016, or 2019 with the latest cumulative update installed
- Exchange Management Shell access with Organization Management or Server Management role
- Local administrator access to the Exchange server
- Performance Monitor (perfmon.exe) access
- Familiarity with PowerShell and Exchange cmdlets
- Event Viewer access to the Application and System logs
- Understanding of MAPI protocol basics
Understanding TooManyObjectsOpenedException
The TooManyObjectsOpenedException is thrown by the Exchange Information Store (Store.exe) when a client session or background process opens more MAPI objects than the configured threshold allows. MAPI objects include messages, folders, attachments, table views, and notification subscriptions. Every time Outlook opens a folder, expands a conversation, or a backup agent enumerates mailbox contents, it creates MAPI objects that consume memory within the Store.exe process.
Exchange enforces these limits through throttling policies to protect server stability. When a single session or mailbox exceeds its allocated object count, the Information Store raises Event ID 9646 in the Application log and rejects further object requests from that session. The immediate visible symptom is that affected Outlook clients experience hangs, disconnections, or “Cannot expand the folder” errors, while server-side you see Store.exe memory growing unchecked.
The critical distinction here is between per-session limits and per-mailbox limits. A single user running Outlook with ten add-ins might have ten separate sessions, each consuming objects. The per-session limit might not be breached, but the aggregate per-mailbox limit can still be exceeded.
How MAPI Object Limits Work
Exchange tracks open objects through the Information Store’s internal resource tracking. Each object type has its own counter:
- Messages open: Number of simultaneously opened message objects
- Folders open: Number of folder objects held in memory
- Attachments open: Attachment streams currently accessed
- Notify subscriptions: Push notification registrations from clients
When any counter exceeds its configured maximum, the store raises the exception and logs it as Event ID 9646 with details about which user and which object type triggered the limit.
Diagnosing the Issue
Step 1: Confirm the Error in Event Logs
Open Event Viewer and navigate to Windows Logs > Application. Filter for Event ID 9646 with source MSExchangeIS. The event detail reveals the affected user, the object type that exceeded the limit, and the current count versus the maximum:
Event ID: 9646
Source: MSExchangeIS
Description: Mapi session "/o=Organization/ou=Exchange Administrative Group/cn=Recipients/cn=jsmith"
exceeded the maximum of 500 objects of type "objtMessage".
This immediately tells you which mailbox is problematic and which object type is being exhausted.
Step 2: Use Get-StoreUsageStatistics
The Get-StoreUsageStatistics cmdlet is your primary diagnostic tool. Run it against the affected mailbox database:
Get-StoreUsageStatistics -Database "Mailbox Database 01" |
Sort-Object -Property DigestCategory -Descending |
Format-Table DisplayName, DigestCategory, SampleCount, SampleValue -AutoSize
This returns resource consumption data for all active mailbox sessions. Look for mailboxes with abnormally high SampleValue numbers, which indicate excessive open objects.
To narrow down to a specific mailbox:
Get-StoreUsageStatistics -Identity "[email protected]" |
Format-List *
Step 3: Check Mailbox Statistics
Use Get-MailboxStatistics to identify mailboxes with unusually large item counts that might contribute to the problem:
Get-MailboxStatistics -Database "Mailbox Database 01" |
Sort-Object -Property ItemCount -Descending |
Select-Object DisplayName, ItemCount, TotalItemSize, LastLogonTime -First 20
Mailboxes with hundreds of thousands of items in a single folder are prime candidates for triggering object limit exceptions, especially when clients try to synchronize the entire folder.
Step 4: Performance Monitor Counters
Add the following counters in Performance Monitor to track real-time MAPI object consumption:
- MSExchangeIS Store\Active Client Logons — total active sessions
- MSExchangeIS Store\Client: RPCs attempted/sec — request rate
- MSExchangeIS Store\Messages Opened/sec — object creation rate
- MSExchangeIS\RPC Requests — concurrent RPC operations
- Process(Store)\Working Set — Store.exe memory consumption
Create a data collector set and run it for at least four hours to capture peak usage patterns. Correlate spikes in open message counts with the timestamps of Event ID 9646 entries.
Common Causes
Misbehaving Outlook Add-ins
Third-party Outlook add-ins are the most frequent culprit. Add-ins that perform background indexing, social media integration, or CRM synchronization often open hundreds of MAPI objects per folder and fail to release them properly. A single user with a poorly coded add-in can exhaust the per-session object limit within minutes.
To identify the offending add-in, check the RPC client information:
Get-RpcClientAccess -Server EX01 | Format-List
Then correlate the client application name in the Event ID 9646 details. Common offenders include outdated versions of Salesforce for Outlook, Thomson Reuters add-ins, and antivirus email scanners.
Third-Party Backup and Archiving Software
Backup agents such as Veeam Explorer for Exchange, Veritas Backup Exec, or Commvault often use MAPI or EWS to enumerate and read mailbox contents during backup windows. If the backup software is configured for item-level recovery, it may open every message in a database simultaneously, easily exceeding object limits.
Check backup job schedules and verify whether the TooManyObjectsOpenedException events correlate with backup windows. Review the backup software configuration for options to throttle MAPI connections or use VSS snapshots instead.
Exchange Search Indexer Issues
The Microsoft Exchange Search Host Controller (HostControllerService) and the content indexing process can malfunction and repeatedly attempt to index the same items, holding excessive objects open. Check the search index health:
Get-MailboxDatabaseCopyStatus * |
Select-Object Name, Status, ContentIndexState, ContentIndexErrorMessage
If ContentIndexState shows Failed or Crawling for extended periods, the indexer may be contributing to object exhaustion. Rebuild the index if necessary:
Stop-Service MSExchangeFastSearch
Stop-Service HostControllerService
# Delete the index catalog folder for the affected database
Remove-Item "D:\ExchangeDatabases\DB01\DB01.Single" -Recurse -Force
Start-Service MSExchangeFastSearch
Start-Service HostControllerService
Public Folder Replication Problems
In environments with public folder mailboxes, replication hierarchy synchronization can cause excessive object creation. Each public folder in the hierarchy requires open objects during synchronization. Organizations with thousands of public folders can easily exceed limits during replication cycles.
Check public folder replication health:
Get-PublicFolderMailboxDiagnostics -Identity "PF_Mailbox01" |
Select-Object -ExpandProperty SyncInfo
Database Corruption
Underlying ESE database corruption can cause the Information Store to repeatedly attempt to access damaged pages, creating and abandoning MAPI objects in the process. If other causes have been eliminated, run an integrity check:
# Dismount the database first
Dismount-Database "Mailbox Database 01" -Confirm:$false
# Run eseutil for integrity check
eseutil /g "D:\ExchangeDatabases\DB01\DB01.edb"
# If issues found, run repair
eseutil /p "D:\ExchangeDatabases\DB01\DB01.edb"
# Defragment to reclaim space
eseutil /d "D:\ExchangeDatabases\DB01\DB01.edb"
# Remount
Mount-Database "Mailbox Database 01"
Exchange Version Object Limits Comparison
| Parameter | Exchange 2013 | Exchange 2016 | Exchange 2019 |
|---|---|---|---|
| Max objects per session (objtMessage) | 500 | 500 | 500 |
| Max folders open per session | 500 | 500 | 500 |
| Max objects per mailbox (total) | 16,000 | 16,000 | 16,000 |
| Max concurrent RPC connections | 40 | 40 | 40 |
| Default RPC timeout (seconds) | 120 | 120 | 120 |
| Store.exe max memory (% of RAM) | Dynamic (up to 75%) | Dynamic (up to 75%) | Dynamic (up to 75%) |
| Throttling policy configurable | Yes (New-ThrottlingPolicy) | Yes (New-ThrottlingPolicy) | Yes (New-ThrottlingPolicy) |
| ESE cache size configurable | Yes (registry) | Yes (registry) | Yes (registry) |
Note that while the default limits are identical across versions, Exchange 2016 and 2019 have improved memory management algorithms that handle object cleanup more aggressively than Exchange 2013.
Step-by-Step Resolution
1. Identify the Immediate Cause
Review the last 24 hours of Event ID 9646 entries and compile a list of affected mailboxes and client applications:
Get-WinEvent -FilterHashtable @{
LogName = 'Application'
ProviderName = 'MSExchangeIS'
ID = 9646
StartTime = (Get-Date).AddHours(-24)
} | Select-Object TimeCreated, Message | Export-Csv C:\temp\9646events.csv
2. Increase Object Limits (Temporary Relief)
If production impact is severe, temporarily increase the per-session object limit via registry:
HKLM\SYSTEM\CurrentControlSet\Services\MSExchangeIS\ParametersSystem
Value: Maximum Allowed Sessions Per User
Type: REG_DWORD
Data: 32 (default is 16, increase to 32 or 64)
For per-object type limits, create a custom throttling policy:
New-ThrottlingPolicy -Name "HighObjectLimit" -RCAMaxConcurrency 40 -RCAPercentTimeInAD 100
Set-Mailbox -Identity "jsmith" -ThrottlingPolicy "HighObjectLimit"
Restart the Microsoft Exchange Information Store service after registry changes.
3. Address the Root Cause
Based on your diagnosis from the previous sections:
- Outlook add-ins: Disable the offending add-in via Group Policy or the Office COM Add-in registry keys. Test with Outlook in safe mode (
outlook.exe /safe). - Backup software: Reconfigure to use VSS-based snapshots rather than MAPI enumeration. Schedule backups during off-peak hours.
- Search indexer: Rebuild the content index catalog for the affected database.
- Public folders: Reduce the hierarchy size, split large public folder mailboxes, or adjust the replication schedule.
- Database corruption: Run
eseutil /dfor offline defragmentation to clean up database inconsistencies.
4. Implement Preventive Monitoring
Create a monitoring rule for Event ID 9646 in your monitoring system (SCOM, Zabbix, or similar) and set up a PowerShell scheduled task to track object counts:
$results = Get-StoreUsageStatistics -Database "Mailbox Database 01" |
Where-Object { $_.SampleValue -gt 400 }
if ($results) {
Send-MailMessage -To "[email protected]" -Subject "MAPI Object Warning" `
-Body ($results | Out-String) -SmtpServer "smtp.contoso.com"
}
Real-World Scenario
Your Exchange 2016 server starts logging Event ID 9646 every few minutes on a Monday morning. Store.exe memory has climbed from its usual 24 GB to 38 GB on a 48 GB server. Users report Outlook disconnections and slow folder loading.
You run Get-StoreUsageStatistics and discover that five mailboxes belonging to the sales team all show elevated object counts. Checking the event details, you see the client application is identified as “Client=MSExchangeRPC” with an additional tag pointing to a third-party CRM add-in.
Further investigation reveals that the IT team deployed a new version of the Dynamics 365 Outlook add-in over the weekend. This version has a known bug where it opens message objects for every contact record but never closes them. Within hours, each sales user’s session accumulates over 450 open message objects, approaching the 500 limit.
The resolution involves three steps: First, you temporarily increase the per-session limit to 1,000 via registry to stop the immediate bleeding. Second, you roll back the CRM add-in to the previous version using Group Policy. Third, you restart the Information Store service during lunch to clear accumulated objects. Over the next 24 hours, Store.exe memory returns to its normal 24 GB baseline and no further 9646 events appear.
Gotchas and Edge Cases
Database Availability Group (DAG) environments: In a DAG, TooManyObjectsOpenedException on one node does not automatically replicate to passive copies. However, if the root cause is a mailbox-level issue (like a corrupted item), the problem will follow the mailbox during database failover. Always check both active and passive nodes.
Coexistence with Exchange 2013 and 2016: During migration coexistence, proxy sessions between servers can multiply MAPI object counts. A single Outlook session to a 2013 mailbox proxied through a 2016 server creates objects on both servers. Monitor both servers during coexistence.
Cached mode versus Online mode: Outlook in Cached Exchange Mode opens fewer concurrent objects than Online Mode because it synchronizes incrementally. However, the initial sync of a Cached Mode profile for a large mailbox (100,000+ items) can temporarily spike object counts above thresholds.
Shared mailboxes with many delegates: A shared mailbox opened by 20 users simultaneously creates 20 separate sessions, each with its own object allocation. The per-mailbox aggregate limit can be reached quickly even if no single session is abusive.
Exchange hybrid with Office 365: Hybrid free/busy lookups and cross-premises mailbox moves create temporary MAPI sessions that consume objects. During large batch migrations, the on-premises server may experience object pressure from the migration endpoint.
Troubleshooting
Event Log Query for Related Errors
Search for related events that often accompany TooManyObjectsOpenedException:
Get-WinEvent -FilterHashtable @{
LogName = 'Application'
ProviderName = 'MSExchangeIS'
ID = 9646, 9660, 9667, 9760
StartTime = (Get-Date).AddDays(-7)
} | Group-Object Id | Select-Object Name, Count | Sort-Object Count -Descending
- Event ID 9660: Session exceeded maximum objects of type
objtFolder - Event ID 9667: RPC connection limit exceeded
- Event ID 9760: MAPI session disconnected due to resource exhaustion
ESE Performance Counters
Monitor these counters to detect database-level issues contributing to high memory:
- Database\Database Cache % Hit — should be above 99%. Below 95% indicates insufficient memory or cache thrashing
- Database\Database Page Evictions/sec — high values mean the cache is full and actively discarding pages
- Database\Log Record Stalls/sec — indicates write contention that can cascade into object retention
Store.exe Memory Does Not Decrease After Fix
If Store.exe memory remains elevated after resolving the root cause, the ESE cache may need manual intervention. Restart the Microsoft Exchange Information Store service during a maintenance window:
Restart-Service MSExchangeIS -Force
In DAG environments, perform a controlled database switchover first:
Move-ActiveMailboxDatabase "Mailbox Database 01" -ActivateOnServer EX02 -Confirm:$false
Then restart the Information Store on the original active server. This ensures zero downtime for users.
Summary
- TooManyObjectsOpenedException occurs when MAPI object limits are exceeded, causing Store.exe memory growth and client disconnections
- Event ID 9646 in the Application log identifies the affected mailbox and the object type that hit the limit
- Get-StoreUsageStatistics is the primary PowerShell cmdlet for diagnosing which mailboxes consume excessive resources
- The five most common causes are misbehaving Outlook add-ins, backup software, search indexer failures, public folder replication issues, and database corruption
- Temporary relief involves increasing per-session limits via registry, but always address the root cause
- eseutil /d offline defragmentation resolves database-level corruption that contributes to object leaks
- Monitor Event IDs 9646, 9660, 9667, and 9760 proactively to catch issues before they impact users
- In DAG environments, always perform controlled switchovers before restarting the Information Store