Exchange ServerTroubleshooting

EWS errors on Exchange Server: 401, 503, ErrorServerBusy and impersonation failures

Apps using EWS fail with 401, 503, ErrorServerBusy or ErrorImpersonateUserDenied. Check authentication, server health, throttling policies, impersonation rights and the EWS logs.

Exchange Web Services (EWS) still carries many on-premises integrations: CRM and calendar sync, room booking, backup, archiving and migration tools. When they fail, the error is usually a 401, a 503, a throttling response or an impersonation refusal, and each points at a different layer. In this post I'll map each error to its cause, show where Exchange logs it, and fix it from the Exchange Management Shell.

Errors this guide fixes

  • The remote server returned an error: (401) Unauthorized.App log / integration error+1 more guide
  • The remote server returned an error: (503) Server Unavailable.App log / integration error
  • ErrorServerBusy: The server cannot service this request right now. Try again later.EWS response
  • ErrorExceededConnectionCountEWS response
  • ErrorImpersonateUserDenied: The account does not have permission to impersonate the requested user.EWS response+1 more guide
  • ErrorExceededSubscriptionCountEWS response
How this guide is organised: Symptoms → Why it happens → How to fix it → Verify the fix → Prevent it next timeFlow diagram of the article's sections in reading order: 1. Symptoms. 2. Why it happens. 3. How to fix it (5 steps: Find the failing requests; Fix 401 Unauthorized; Fix 503 Server Unavailable; Fix throttling errors; Fix ErrorImpersonateUserDenied). 4. Verify the fix. 5. Prevent it next time. Toolbox: Set-WebServicesVirtualDirectory, Restart-WebAppPool, ErrorServerBusy, ErrorImpersonateUserDenied, ErrorExceededConnectionCount.1Symptoms2Why it happens3How to fix it4Verify the fix5Prevent it nexttime1Find the failingrequests2Fix 401Unauthorized3Fix 503 ServerUnavailable4Fix throttling errors5FixErrorImpersonate…TOOLBOXSet-WebServicesVirtualDirectoryRestart-WebAppPoolErrorServerBusyErrorImpersonateUserDeniedErrorExceededConnectionCountHow this guide is organised: Symptoms → Why it happens → How to fix it → Verify the fix → Prevent it next timeFlow diagram of the article's sections in reading order: 1. Symptoms. 2. Why it happens. 3. How to fix it (5 steps: Find the failing requests; Fix 401 Unauthorized; Fix 503 Server Unavailable; Fix throttling errors; Fix ErrorImpersonateUserDenied). 4. Verify the fix. 5. Prevent it next time. Toolbox: Set-WebServicesVirtualDirectory, Restart-WebAppPool, ErrorServerBusy, ErrorImpersonateUserDenied, ErrorExceededConnectionCount.1Symptoms2Why it happens3How to fix it1Find the failing requests2Fix 401 Unauthorized3Fix 503 Server Unavailable4Fix throttling errors5Fix ErrorImpersonateUserDenied4Verify the fix5Prevent it next timeTOOLBOXSet-WebServicesVirtualDirectoryRestart-WebAppPoolErrorServerBusyErrorImpersonateUserDeniedErrorExceededConnectionCount
At a glance: how this guide is organised · 5 fix steps · 5 key tools

Note: Microsoft's EWS retirement covers Exchange Online, not EWS on Exchange Server. If your apps also talk to Exchange Online, see EWS switch-off in Exchange Online.

Symptoms#

The application's log or error dialog shows one of these:

Text
The remote server returned an error: (401) Unauthorized.
The remote server returned an error: (503) Server Unavailable.
ErrorServerBusy: The server cannot service this request right now. Try again later.
ErrorExceededConnectionCount
ErrorImpersonateUserDenied: The account does not have permission to impersonate the requested user.
  • 401 and 503 are HTTP status codes and show up in the IIS log against POST /EWS/Exchange.asmx.
  • EWS errors such as ErrorServerBusy and ErrorImpersonateUserDenied arrive inside a SOAP response that can carry HTTP 500, so a 500 for EWS usually means "read the response body", not "the server crashed".
  • Throttling errors cluster at busy times; impersonation errors hit some mailboxes and not others.

Why it happens#

ErrorLayerUsual causes
401AuthenticationWrong, expired or locked service account; app needs Basic but it's off on the EWS virtual directory; Windows authentication through a TLS-terminating device with Extended Protection on; expired Auth certificate for OAuth
503AvailabilityEWS app pool stopped or crashing; server left in maintenance mode; load balancer sending traffic to a drained server
ErrorServerBusy, ErrorExceededConnectionCountThrottlingApp exceeds its budget or concurrent connections; Exchange also slows EWS callers while a resource such as a mailbox database is unhealthy
ErrorImpersonateUserDeniedPermissionsService account lacks the ApplicationImpersonation role, or the mailbox is outside its scope

How to fix it#

1. Find the failing requests#

PowerShell
$ews = Join-Path $env:ExchangeInstallPath "Logging\Ews"
Get-ChildItem $ews | Sort-Object LastWriteTime | Select-Object -Last 3 | Select-String "svc-crm" | Select-Object -Last 20
Get-ChildItem C:\inetpub\logs\LogFiles\W3SVC1\*.log | Sort-Object LastWriteTime | Select-Object -Last 1 |
    Select-String "/EWS/Exchange.asmx" | Select-Object -Last 20

The EWS log on the server that processed the request records the calling account and the outcome, so searching for the service account or an error code finds failures quickly; Logging\HttpProxy\Ews holds the front-end view. In the IIS log, a 401 followed by a 200 is the normal authentication handshake. Repeated 401s with an empty username mean the app never authenticates.

2. Fix 401 Unauthorized#

PowerShell
Get-WebServicesVirtualDirectory -Server EX01 | Format-List Server, InternalUrl, ExternalUrl, *Authentication*
  • Keep Windows authentication enabled, and OAuth if you use hybrid features. If an app can only do Basic, it fails until you run Set-WebServicesVirtualDirectory "EX01\EWS (Default Web Site)" -BasicAuthentication $true; do that only if you must, and only over HTTPS.
  • Check the service account for lockouts, expired passwords and "must change password" flags, then test it with the request in Verify the fix.
  • If the app reaches Exchange through a load balancer or proxy that terminates TLS, Extended Protection breaks Windows authentication.
  • OAuth-based apps and hybrid features fail once the Auth certificate expires; see renewing the Auth certificate.

3. Fix 503 Server Unavailable#

PowerShell
Get-ServerComponentState EX01 | Where-Object State -ne "Active" | Format-Table Component, State
Import-Module WebAdministration
Get-ChildItem IIS:\AppPools | Where-Object { $_.Name -like "MSExchange*" } | Select-Object Name, State
Get-HealthReport EX01 | Where-Object { $_.HealthSet -like "EWS*" } | Format-Table HealthSet, AlertValue

ForwardSyncDaemon and ProvisioningRps are normally Inactive. Anything else Inactive, such as ServerWideOffline, means the server is still in maintenance mode; bring it back with the exit steps in DAG maintenance mode. Restart-WebAppPool MSExchangeServicesAppPool recycles the back-end EWS app pool. On the load balancer, probe /ews/healthcheck.htm so a server with a broken EWS stack leaves the pool.

4. Fix throttling errors#

PowerShell
Get-ThrottlingPolicyAssociation svc-crm | Format-List
Get-ThrottlingPolicy | Format-Table Name, IsDefault, ThrottlingPolicyScope, EwsMaxConcurrency, EwsMaxSubscriptions -AutoSize

New-ThrottlingPolicy -Name "EWS-svc-crm" -ThrottlingPolicyScope Regular -EwsMaxConcurrency 50 -EwsMaxSubscriptions 500
Set-ThrottlingPolicyAssociation -Identity svc-crm -ThrottlingPolicy "EWS-svc-crm"

ErrorExceededConnectionCount maps to EwsMaxConcurrency and ErrorExceededSubscriptionCount to EwsMaxSubscriptions. ErrorServerBusy means Exchange is pushing back; since Exchange 2013 the response suggests a wait time (BackOffMilliseconds) that a well-behaved app honours. The values above are examples: size them with the vendor, apply the policy only to the service account, and leave the default policy protecting everyone else. If the errors coincide with database or disk problems, higher limits won't help; fix the resource.

5. Fix ErrorImpersonateUserDenied#

PowerShell
Get-ManagementRoleAssignment -Role ApplicationImpersonation -GetEffectiveUsers |
    Format-Table EffectiveUserName, CustomRecipientWriteScope -AutoSize

New-ManagementScope -Name "CRM mailboxes" -RecipientRestrictionFilter "MemberOfGroup -eq 'CN=CRM Users,OU=Groups,DC=contoso,DC=com'"
New-ManagementRoleAssignment -Name "Impersonation-svc-crm" -Role ApplicationImpersonation -User svc-crm `
    -CustomRecipientWriteScope "CRM mailboxes"

The error means the assignment is missing or the target mailbox is outside its scope. Allow for AD replication after a change. Exchange Online has retired this role, but Exchange Server still uses it. Ask the vendor to send an X-AnchorMailbox header with the impersonated address, which Microsoft recommends for impersonation.

Verify the fix#

Send one real request as the service account. Remove the ExchangeImpersonation element to test the credentials alone:

PowerShell
$soap = @'
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
  xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013_SP1" />
    <t:ExchangeImpersonation><t:ConnectingSID><t:PrimarySmtpAddress>jane@contoso.com</t:PrimarySmtpAddress></t:ConnectingSID></t:ExchangeImpersonation>
  </soap:Header>
  <soap:Body>
    <m:GetFolder>
      <m:FolderShape><t:BaseShape>IdOnly</t:BaseShape></m:FolderShape>
      <m:FolderIds><t:DistinguishedFolderId Id="inbox" /></m:FolderIds>
    </m:GetFolder>
  </soap:Body>
</soap:Envelope>
'@
$r = Invoke-WebRequest -Uri https://mail.contoso.com/EWS/Exchange.asmx -Method Post -Body $soap -UseBasicParsing `
    -ContentType "text/xml; charset=utf-8" -Credential (Get-Credential contoso\svc-crm) -Headers @{ "X-AnchorMailbox" = "jane@contoso.com" }
([xml]$r.Content).Envelope.Body.GetFolderResponse.ResponseMessages.GetFolderResponseMessage.ResponseCode
  • Good is NoError. A mailbox outside the scope should fail with ErrorImpersonateUserDenied, which proves the scope works. (Windows PowerShell treats that HTTP 500 as an error; in PowerShell 7, add -SkipHttpErrorCheck to read the body.)
  • The IIS log shows the service account's requests returning 200, and the EWS log shows no new ErrorServerBusy entries at peak times.

Prevent it next time#

  • Use one service account per app and record its impersonation scope and throttling policy.
  • Probe /ews/healthcheck.htm on the load balancer, and check component states after every update.
  • Track the Auth certificate's expiry date.
  • Inventory EWS apps before you move mailboxes to Exchange Online.

References#

Written and checked against current Microsoft Learn documentation. Test changes with a pilot group before rolling them out to everyone, and if an admin center path has moved since, search for the setting name instead.

Spotted a mistake, or did this fix work differently for you? Email me or message me on LinkedIn — corrections are credited in the article.

Written by

Omer Eltayeb

Intune Subject Matter Expert in Cairo, Egypt, former Microsoft Cloud Solutions Architect, Microsoft Certified Trainer and Microsoft Innovative Educator Expert (2024–26) and Microsoft Elevate Educator Expert (2026–27). I share practical, step-by-step guides, study plans, scripts and toolkits for Microsoft Intune, Configuration Manager, Microsoft Entra ID, Microsoft Defender, Exchange and Microsoft 365 with the community.

Microsoft Certified Trainer (MCT) 2026Microsoft Innovative Educator Expert 2025–2026Microsoft Elevate Educator Expert 2026–2027ISC2 Certified Information Systems Security Professional (CISSP)Microsoft 365 Certified: Enterprise Administrator Expert (MS-102)