How to Fix Exchange Online
Why Exchange Online Troubleshooting Feels Impossible
I've seen this exact situation play out hundreds of times. Everything was working fine yesterday , email flowing, calendars syncing, Outlook connected , and then Monday morning arrives and half your organization can't send mail, Outlook keeps throwing 0x800CCC0E or 550 5.7.64 NDRs, and your helpdesk queue is exploding. Exchange Online troubleshooting is genuinely hard because Microsoft has distributed the problem space across at least six different admin portals, four different PowerShell modules, and a dozen interdependent services.
The frustration is real. I get it. Microsoft's error messages are notoriously unhelpful, a bounce-back saying "550 5.1.8 Access denied, bad outbound sender" could mean your IP is blocklisted, your SPF record is broken, your send connector misconfigured, or your account is compromised and being throttled. Same error code, four completely different root causes. That's Exchange Online in a nutshell.
Here's what's actually going on under the hood. Exchange Online sits on top of Microsoft 365's shared infrastructure, which means your mail flow doesn't just depend on your tenant configuration, it also depends on Microsoft's global transport layer, the specific datacenter region your tenant is assigned to, and the health of dependent services like Azure Active Directory, Entra ID, and the Microsoft Authentication Library (MSAL). A hiccup in any of those can surface as what looks like a mail delivery problem.
The most common Exchange Online troubleshooting scenarios I see fall into five buckets: mail flow failures (email not sending or receiving), client connectivity issues (Outlook can't connect, throws disconnected errors), authentication breakdowns (Modern Auth failures, ADAL token errors, MFA loops), calendar and free/busy problems (hybrid deployments, cross-tenant sharing), and transport rule misfires (emails going to spam, getting blocked, or stripping attachments unexpectedly).
The thing Microsoft doesn't tell you upfront: around 40% of Exchange Online troubleshooting tickets are caused by something completely outside Exchange itself, a broken SPF/DKIM/DMARC record, an expired OAuth app secret, a Conditional Access policy that silently started blocking Outlook, or a DNS TTL that hasn't propagated yet. You have to rule those out first before you dig into Exchange-specific settings.
The Quick Fix, Try This First
Before you spend an hour digging through the Exchange admin center, do these three things in order. They solve the majority of Exchange Online issues I see in practice.
Step 1: Check Microsoft's own service health. Go to admin.microsoft.com → Health → Service health. Look specifically for advisories or incidents under Exchange Online and Microsoft 365 suite. You'd be amazed how often what looks like a tenant-specific problem is actually a Microsoft-side incident that's been posted for two hours. Don't waste time troubleshooting your end if their datacenter is on fire.
Step 2: Run the Microsoft Support and Recovery Assistant (SARA). Download it from aka.ms/SaRA. This tool is underrated, it runs dozens of automated diagnostics against your Outlook profile, Exchange connection settings, Autodiscover chain, and authentication tokens. It takes about four minutes and catches roughly 60% of common issues automatically. Run it on the affected machine, let it complete, and read the detailed report it generates.
Step 3: Test mail flow from the Exchange admin center. Log into admin.exchange.microsoft.com → Mail flow → Message trace. Enter the sender and recipient addresses and run a trace for the last two hours. The detailed trace result will tell you exactly where a message stopped, whether it was rejected at the edge, quarantined by a transport rule, blocked by a connector policy, or simply never left the sender's outbox due to a client-side issue.
If those three steps don't resolve the problem or clearly identify the cause, work through the full troubleshooting steps below.
This is the single most overlooked root cause in Exchange Online troubleshooting. When your outbound mail gets rejected or lands in recipients' spam folders, broken DNS authentication records are the culprit more often than any Exchange configuration problem. I've walked into organizations where the SPF record was simply missing the include:spf.protection.outlook.com mechanism, a two-minute fix that had been causing NDRs for months.
Open PowerShell and run a quick check:
# Check SPF record
Resolve-DnsName -Name yourdomain.com -Type TXT | Where-Object { $_.Strings -match "v=spf1" }
# Check DKIM selector records
Resolve-DnsName -Name selector1._domainkey.yourdomain.com -Type CNAME
Resolve-DnsName -Name selector2._domainkey.yourdomain.com -Type CNAME
Your SPF record must include include:spf.protection.outlook.com and should end with ~all or -all. If it's missing or malformed, log into your DNS provider and add or correct it. Changes can take up to 48 hours to propagate, but typically resolve within 30 minutes for most resolvers.
For DKIM, head to the Exchange admin center → Mail flow → DKIM. Both selectors (selector1 and selector2) should show Status: Enabled. If they show No DKIM keys saved for this domain, click Enable and then update the CNAME records in your DNS with the values Microsoft provides. Do not enable DKIM until those DNS records are published, you'll cause an immediate delivery failure.
DMARC is optional but increasingly important for deliverability. A minimal record looks like: v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com. Start with p=none to collect reports before enforcing.
Once your DNS records are correct, recheck with the Microsoft Remote Connectivity Analyzer at testconnectivity.microsoft.com, use the Outbound SMTP Email test. A passing result here means your outbound authentication chain is clean.
When Outlook clients show Disconnected, Trying to connect, or throw error 0x8004011D or Cannot start Microsoft Outlook. Cannot open the Outlook window, the problem is almost always in the Autodiscover chain or the MAPI-over-HTTPS configuration. Don't let users create new profiles or reinstall Outlook until you've confirmed the service endpoint is actually reachable.
Connect to Exchange Online PowerShell first:
Install-Module -Name ExchangeOnlineManagement -Force
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@yourdomain.com
Then test Outlook connectivity for a specific user:
Test-OutlookConnectivity -ProbeIdentity OutlookMapiHttp.Probe -MailboxId user@yourdomain.com
Also check Autodiscover directly from the Remote Connectivity Analyzer. Go to testconnectivity.microsoft.com → Outlook Connectivity → Outlook Autodiscover. Enter the affected user's email and credentials. The tool walks through every step of the Autodiscover lookup chain and flags exactly where it fails, whether it's an SRV record missing, a 401 redirect loop, or a certificate name mismatch on a hybrid CAS server.
For hybrid environments, this is where things get messy. If your on-premises Exchange server is still published as the Autodiscover endpoint but users are in Exchange Online, you'll see Autodiscover returning on-premises settings for cloud mailboxes. Fix this by setting the on-premises Autodiscover service to redirect cloud-homed users:
# Run on-premises Exchange Management Shell
Set-ClientAccessServer -Identity "EXCH01" -AutoDiscoverServiceInternalUri https://autodiscover.yourdomain.com/autodiscover/autodiscover.xml
If the test passes but Outlook still won't connect on a specific machine, delete the existing Outlook profile (Control Panel → Mail → Show Profiles → select the profile → Remove) and create a new one. Sometimes the cached token in the credential store is corrupted. Open Credential Manager (Win + R → control keymgr.dll), find and delete any entries starting with MicrosoftOffice16 or msteams, then relaunch Outlook.
Mail not arriving is the most urgent Exchange Online troubleshooting scenario. It feels like email just vanished, and sometimes it literally did, if a transport rule is silently dropping messages. Here's how to find it fast.
In the Exchange admin center (admin.exchange.microsoft.com), go to Mail flow → Message trace → Start a trace. Set the time range to at least 4 hours before the reported problem. Enter the sender's email, the recipient's email, and click Search.
Read the Status column carefully:
- Delivered, Exchange delivered it. The problem is on the recipient's end (wrong folder, client filtering, mailbox rule).
- Failed, Delivery attempt failed. Click into the trace for the specific SMTP error code and action.
- Pending, Message is still in the transport queue. Could be a routing loop, slow connector, or Microsoft infrastructure delay.
- FilteredAsSpam, Anti-spam policy blocked it. Check Security → Email & collaboration → Policies & rules → Threat policies → Anti-spam.
- No messages found, Exchange never received the message. The problem is on the sending side, check the sender's outbox, their mail client logs, or their sending server's SMTP logs.
If the trace shows a transport rule action (like DeleteMessage or Redirect), go to Mail flow → Rules and review every rule that could match the sender/recipient combination. Sort by priority, higher-priority rules run first and can prevent lower rules from executing entirely.
For messages stuck in the outbound queue going to external recipients, check if your tenant's outbound connector is misconfigured. Run this in Exchange Online PowerShell:
Get-OutboundConnector | Format-List Name, Enabled, SmartHosts, UseMxRecord, TlsSettings, ConnectorType
If UseMxRecord is False and the SmartHosts value points to a dead or misconfigured relay, that's your culprit. Either fix the smart host address or set UseMxRecord back to True for internet delivery.
Authentication failures are behind a huge portion of Exchange Online troubleshooting cases, and they're getting more common as Microsoft tightens down on Basic Auth (which was fully disabled for Exchange Online in October 2022). If your users see Password incorrect prompts that loop, Need password in Outlook's status bar, or MFA prompts that never complete, this is the section you need.
First, verify Modern Authentication is enabled on your tenant:
Connect-ExchangeOnline -UserPrincipalName admin@yourdomain.com
Get-OrganizationConfig | Select-Object OAuth2ClientProfileEnabled
The value must be True. If it's False, enable it:
Set-OrganizationConfig -OAuth2ClientProfileEnabled $true
On the client side, confirm the Outlook client supports Modern Auth. Outlook 2013 requires a registry key that Microsoft doesn't set by default:
# Run in Registry Editor or via PowerShell as admin
# For 32-bit Office on 64-bit Windows:
New-ItemProperty -Path "HKCU:\Software\Microsoft\Office\15.0\Common\Identity" -Name "EnableADAL" -Value 1 -PropertyType DWORD -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Office\15.0\Common\Identity" -Name "Version" -Value 1 -PropertyType DWORD -Force
For Outlook 2016 and later, Modern Auth is on by default, but Conditional Access policies can still block it. Go to entra.microsoft.com → Protection → Conditional Access → Sign-in logs. Filter by the affected user and look for Failure entries. The Conditional Access tab inside each log entry will show you exactly which policy triggered and what condition caused the block, usually it's a device compliance requirement, a location restriction, or an MFA requirement that the client isn't satisfying.
Token cache corruption is also common after password resets. Have the user open Credential Manager (search in Start menu), go to Windows Credentials, and delete every entry containing outlook, office, mso, or microsoftoffice. Then restart Outlook and sign in fresh. This clears the stale OAuth tokens that are causing the loop.
Shared mailbox access failures, delegate send-on-behalf errors, and calendar delegation breakdowns are incredibly common Exchange Online troubleshooting tickets. The symptoms vary, Outlook shows You don't have permission to access this mailbox, or the delegate can open the mailbox but not send from it, or Send As works but Send on Behalf doesn't. Each of these is a different permission layer.
Start by auditing the actual permissions on the mailbox in question:
# Full mailbox access (for shared mailboxes, opened as additional account)
Get-MailboxPermission -Identity sharedmailbox@yourdomain.com | Where-Object { $_.IsInherited -eq $false } | Format-Table User, AccessRights
# Send As permission (appears to come FROM that mailbox)
Get-RecipientPermission -Identity sharedmailbox@yourdomain.com | Format-Table Trustee, AccessRights
# Send on Behalf permission (shows "on behalf of" in recipient header)
Get-Mailbox -Identity sharedmailbox@yourdomain.com | Select-Object GrantSendOnBehalfTo
If the user is missing from the output, add them:
# Add full access
Add-MailboxPermission -Identity sharedmailbox@yourdomain.com -User user@yourdomain.com -AccessRights FullAccess -InheritanceType All -AutoMapping $true
# Add Send As
Add-RecipientPermission -Identity sharedmailbox@yourdomain.com -Trustee user@yourdomain.com -AccessRights SendAs
# Add Send on Behalf
Set-Mailbox -Identity sharedmailbox@yourdomain.com -GrantSendOnBehalfTo @{Add="user@yourdomain.com"}
One thing that catches people off guard: AutoMapping (the feature that automatically opens a shared mailbox in Outlook when you have Full Access) requires the -AutoMapping $true flag and only works when the user profile was created after the permission was granted. If a user had their profile set up before they received Full Access, remove and re-add the permission with AutoMapping enabled, then delete and recreate the Outlook profile. The mailbox will appear in the left nav automatically after a few minutes.
For calendar delegation issues specifically, check the calendar sharing policy applied to the mailbox. In the Exchange admin center, go to Organization → Sharing and verify the Default Sharing Policy includes Calendar sharing with all domains at the appropriate permission level. Internal delegation problems are sometimes caused by the Default sharing policy being overly restrictive.
Advanced Exchange Online Troubleshooting
If the steps above haven't resolved your issue, you're in the territory where things get genuinely complex. This is where enterprise environments, hybrid deployments, and edge-case connector configurations live.
Event Viewer and Outlook Logging
Enable detailed Outlook logging before your next reproduction attempt. Hold Ctrl while clicking the Outlook icon in the system tray → Other User's Folder is NOT what you want here, instead open Outlook, go to File → Options → Advanced → scroll to Other section → check Enable troubleshooting logging (requires restarting Outlook). Restart Outlook, reproduce the issue, then find logs at %TEMP%\Outlook Logging\. Look for OPMLog files, search for Error or FAILED in a text editor.
In Event Viewer (Win + R → eventvwr.msc), check Windows Logs → Application and filter by Source Outlook. Event ID 27 indicates an Autodiscover failure. Event ID 64 usually points to a certificate trust issue, common in hybrid environments where the on-premises Exchange certificate isn't trusted by the client machine.
Group Policy and Registry-Level Fixes
In enterprise environments, Group Policy can override Exchange Online client settings in ways that are hard to spot. The most common culprit is a GPO that enforces Basic Authentication or disables Modern Auth across the org. Check with:
# Check Outlook auth registry settings
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Identity" -ErrorAction SilentlyContinue
Get-ItemProperty -Path "HKCU:\Software\Policies\Microsoft\Office\16.0\Common\Identity" -ErrorAction SilentlyContinue
Values under Policies are GPO-enforced and override user settings. If EnableADAL is set to 0 under the Policies key, your Group Policy is actively breaking Modern Auth. Find and modify the corresponding GPO in Group Policy Management (search in Start), look under User Configuration → Administrative Templates → Microsoft Office 2016 → Security Settings → Identity Platform.
Hybrid Configuration Troubleshooting
Hybrid Exchange deployments where some mailboxes are on-premises and some are in Exchange Online add a significant layer of complexity. Free/busy lookup failures, cross-premises meeting invites that don't show availability, and OAuth trust errors are all common. Run the Hybrid Configuration Wizard from your on-premises Exchange server and check the OAuth configuration:
# On-premises Exchange Management Shell
Test-OAuthConnectivity -Service EWS -TargetUri https://outlook.office365.com/ews/exchange.asmx -Mailbox onpremuser@yourdomain.com | Format-List
An OAuth token request failed result means the trust relationship between your on-premises Exchange and Exchange Online has broken, often happens after cert renewal. Rerun the Hybrid Configuration Wizard to refresh the OAuth certificate and re-establish the trust.
Connector and Transport Rule Deep-Dive
For organizations with third-party email filtering (Mimecast, Proofpoint, Barracuda), the inbound and outbound connectors must be configured to match the filtering service's IP ranges and certificate requirements. Use Get-InboundConnector and Get-OutboundConnector to review all connector settings and compare against your filtering vendor's published configuration requirements. A connector with TlsSettings: DomainValidation pointing to a vendor that presents a different TLS certificate than expected will silently drop messages.
Prevention & Best Practices
The best Exchange Online troubleshooting is the troubleshooting you never have to do. Most of the issues I've described above are entirely preventable with the right monitoring and hygiene in place. Here's what I recommend to every organization running Exchange Online.
Set up proactive monitoring. Microsoft 365 has built-in service health APIs that you can query programmatically. Subscribe to service health notifications in the admin center: Health → Service health → Customize → turn on email alerts for Exchange Online incidents. You want to know about Microsoft-side problems before your users do, not after.
Audit your transport rules quarterly. Transport rules accumulate over time, people create them for specific use cases, those use cases change, but the rules stay. An unmaintained ruleset with dozens of overlapping conditions is a ticking time bomb for mail flow problems. Every quarter, run Get-TransportRule | Select-Object Name, Priority, State, Description | Sort-Object Priority | Export-Csv transport_rules.csv and review with your team. Delete or disable anything that isn't actively needed.
Monitor mailbox sizes and quotas. When a mailbox hits its quota, Exchange Online starts rejecting inbound mail with 452 4.2.2 The mailbox is over its storage limit. Users don't always see this clearly in their Outlook client. Set up a monthly report: Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | Where-Object {$_.TotalItemSize -gt 40GB} | Select-Object DisplayName, TotalItemSize, ItemCount. Proactively archive or increase quotas for approaching-limit mailboxes before they hit the wall.
Regularly test your Autodiscover and mail flow. Add a weekly check using the Remote Connectivity Analyzer's automated tests. Microsoft also provides the Test-MAPIConnectivity and Test-MailFlow cmdlets you can run from Exchange Online PowerShell as part of a scheduled health check script.
- Enable DKIM signing for every domain in your tenant, it's free, takes 10 minutes, and immediately improves deliverability scores
- Turn on Safe Attachments and Safe Links in Defender for Office 365, these also help with false-positive spam issues by giving Microsoft better reputation signals for your traffic
- Create a dedicated "break-glass" admin account with Exchange Admin role that uses a non-custom domain (e.g.,
admin@yourorg.onmicrosoft.com), this stays functional even during custom domain DNS failures - Document your connector configuration and transport rules in a SharePoint page with the date last reviewed, institutional knowledge about why specific rules exist saves hours during incident response
Frequently Asked Questions
Why is my Exchange Online email going to spam for external recipients?
This almost always comes down to SPF, DKIM, or DMARC records being missing or misconfigured for your sending domain. External mail servers check these DNS records to verify your email is legitimate, if they can't confirm it, they flag it as suspicious. Start by checking your SPF record includes include:spf.protection.outlook.com, then verify DKIM is enabled in the Exchange admin center under Mail flow → DKIM. Also check that your tenant's sending IP ranges haven't appeared on a public blocklist, use MXToolbox's Blacklist Check (mxtoolbox.com/blacklists.aspx) to verify. If you're listed, submit a delisting request to each blocklist operator.
Outlook keeps asking for my Exchange Online password in a loop, how do I stop it?
This is usually a corrupted or stale OAuth token in the Windows Credential Manager. Open Credential Manager from the Start menu, click Windows Credentials, and delete every entry with "outlook", "office", or "microsoft" in the name. Then open Registry Editor and check HKCU\Software\Microsoft\Office\16.0\Common\Identity, make sure EnableADAL is set to 1. If a Group Policy is pushing EnableADAL = 0 under the Policies hive, that's forcing Basic Auth which Microsoft has disabled, causing the infinite loop. Escalate that registry value to your IT admin to fix the GPO.
How do I check if an email was actually delivered by Exchange Online vs. still stuck in queue?
Run a Message Trace in the Exchange admin center (Mail flow → Message trace). A Delivered status means Exchange successfully handed it off, if the recipient still doesn't see it, check their Junk Email folder, Focused Inbox settings, and any inbox rules that might be auto-archiving or deleting messages. A Pending status means it's still in the transport queue, this is usually temporary but if it persists more than 30 minutes, check your outbound connectors and Microsoft's service health for any active incidents on the Exchange Online transport layer.
Can I still use Basic Authentication with Exchange Online in 2026?
No, Microsoft permanently disabled Basic Authentication for Exchange Online in October 2022. This affects IMAP, POP3, SMTP AUTH (for client submission), EWS, Remote PowerShell, and ActiveSync when using credentials directly. Any application or device still using Basic Auth will fail with a 535 5.7.3 Authentication unsuccessful error. You need to migrate to OAuth 2.0 (Modern Auth). For applications that can't support OAuth natively, like some older printers or scanners using SMTP relay, use Microsoft 365's SMTP relay option with a connector instead of authenticated SMTP submission.
My shared mailbox stopped appearing automatically in Outlook, how do I fix AutoMapping?
AutoMapping is controlled by a flag set at the time the Full Access permission is granted, not something you can toggle after the fact. To fix it, you need to remove and re-add the permission with AutoMapping explicitly enabled. Run in Exchange Online PowerShell: Remove-MailboxPermission -Identity sharedmailbox@domain.com -User user@domain.com -AccessRights FullAccess then Add-MailboxPermission -Identity sharedmailbox@domain.com -User user@domain.com -AccessRights FullAccess -AutoMapping $true. The mailbox should reappear in Outlook within 5-15 minutes. If the user has already opened Outlook in the meantime, close and reopen it once after the permission propagates.
Exchange Online message trace says "Delivered" but the user says they never got the email, what now?
If message trace confirms delivery to the mailbox, Exchange did its job, the investigation now shifts to the mailbox itself. Check three places: first, the Junk Email folder (especially if the user uses a mobile client where Junk is hidden by default); second, any inbox rules that might be moving or deleting messages (go to Outlook Web Access → Settings → Mail → Rules and review all active rules); third, the Focused Inbox filter, which silently redirects certain messages to the "Other" tab. If none of those explain it, connect to Exchange Online PowerShell and run Search-Mailbox -Identity user@domain.com -SearchQuery "subject:<subject line>" -EstimateResultOnly to confirm the item actually exists in the mailbox database.