Microsoft 365 Outage: When Failover Overloads the Fleet
The Microsoft 365 outage of Nov 12 shows how health checks and failover can overload a fleet. What on-call teams should change in systems and response.

The Microsoft 365 outage of November 12, 2026 is a textbook example of a failure that most teams plan for in the wrong way. Exchange Online incident EX1550543 opened at 16:17 UTC, users in the Americas lost access to their mailboxes first, and within hours Microsoft was warning that connectivity could be affected in any region. The broader advisory, MO1550821, pulled in Teams, SharePoint Online, Microsoft 365 Copilot and Defender XDR. What makes this incident worth studying is not its size. It is what Microsoft said about the load: it was elevated, but not because traffic went up. It went up because a large number of servers were unexpectedly unavailable, and the servers that remained could not carry the work.
That is a cascading failover problem, and it is one that lives in almost every fleet that uses health checks, load balancers and automatic removal of unhealthy nodes. In other words, it lives in yours. This post walks through what is publicly known about the outage, the failure pattern it fits, why recovery from this kind of event is slow and fragile, and the concrete changes on-call teams can make to their systems and their response process so the same shape of failure hurts less.
A note on sourcing before we start. As of November 13, Microsoft had not published a post-incident review and had not confirmed a root cause. The details below come from Microsoft's service health updates as relayed by reporting such as SecurityWeek's coverage of the incident. Where we interpret the mechanism, we say so. Treat the specifics as provisional until Microsoft's own review lands.
What happened in the Microsoft 365 outage
The timeline as reported
Pieced together from Microsoft's status updates as reported publicly, the sequence looked roughly like this:
- 16:17 UTC, November 12: Exchange Online incident EX1550543 opens. Users in the Americas cannot connect to their mailboxes in Outlook on the web, desktop and mobile.
- About 18:00 UTC: Microsoft widens the warning, saying the issue may affect Microsoft 365 connectivity for users in any region. Downdetector reports for Outlook climb past 100,000.
- About 18:30 UTC: The broader incident MO1550821 opens, covering services that depend on Exchange Online, including parts of Teams, SharePoint Online, Copilot and Defender XDR.
- About 19:00 UTC: Microsoft pauses deployments and configuration changes.
- Afternoon and evening ET: Microsoft reports that affected servers are failing automated health checks, tests a workaround that bypasses the component that processes those checks, investigates elevated processor usage, and begins rolling back a recent network configuration change that correlates with the start of impact.
- Overnight into November 13: Restarting affected servers shows improvement in some regions, but recovery is not sustained everywhere. Microsoft states there is no indication of malicious activity.
What broke and what did not
The blast radius followed the dependency graph, not the product list. Features that depend on Exchange Online failed: mail, calendars, meeting scheduling and invites, contact sync, and Copilot answers that needed mail or calendar data. Some Google Workspace users who read their mail through Outlook clients also reported trouble, which is a reminder that the client is a dependency too. Meanwhile, parts of the suite that do not route through Exchange Online stayed largely functional. Teams chat and calls mostly worked even while Teams calendars did not.
For on-call teams, that split matters. Many companies discovered on November 12 that their "Teams is up" assumption was only half true. You could message a colleague, but you could not reliably schedule the bridge call, send the customer email, or see who was supposed to be on shift if that schedule lived in an Outlook calendar.
The failure pattern: when failover overloads the fleet
How health checks turn a partial failure into a total one
Microsoft's own description is the most useful part of the public record. Paraphrasing the updates: a large number of servers became unavailable, the remaining servers absorbed their load, and a process that sets up secure connections on those servers became overwhelmed, so they stopped processing requests. Affected servers were failing automated health checks. Servers that were restored could become unresponsive again once traffic reached them.
Microsoft has not said this explicitly, but that sequence matches a well documented pattern. Here is the generic version:
- Some fraction of a fleet becomes slow or unavailable for any reason: a bad config, a bad host image, a dependency stall.
- The health check system marks those nodes unhealthy and the load balancer removes them.
- Their traffic is redistributed to the survivors, which were sized for a normal share, not for an extra 20 or 40 percent.
- The survivors get slower. The expensive part of each request (connection setup and TLS handshakes are a classic example, because they are CPU heavy) starts to queue.
- Slow nodes now fail their health checks too, because the health check is served by the same overloaded process or competes for the same CPU.
- More nodes are removed, the survivors get even more load, and the fleet spirals down.
Google's SRE book describes this dynamic in its chapter on addressing cascading failures, naming server overload as the most common cause and noting how load shifted from failed instances pushes the rest past their limits. Amazon's Builders' Library makes the same point in its article on using load shedding to avoid overload, warning that removing servers from service while they are overloaded can cause a downward spiral. Neither is a description of Microsoft's architecture. They describe the class of failure that Microsoft's public wording fits.
Why "traffic did not go up" is the key clue
Most capacity alerting is built around demand. Dashboards show requests per second, and teams scale when the line goes up. In a cascading failover event, demand can be completely flat. What changes is supply: the number of healthy servers available to serve that demand. If you only alert on traffic, you will see nothing unusual until error rates explode. If you alert on the ratio of demand to healthy capacity, you see the problem the moment the fleet starts to shrink.
This is the first practical takeaway: watch the size of your healthy pool as a first-class signal. A sudden drop in healthy instances, even with no customer impact yet, should page someone. It is the earliest warning you get.
Why the correlated config change matters
Microsoft said it was reverting a recent network configuration change that correlated with the start of impact, after an earlier update said no recent change was correlated. That reversal is common in real incidents and worth naming. The first look at a change log often misses network or infrastructure changes that are not tracked in the same place as application deploys. If your change timeline only shows application releases, you will tell yourself "nothing changed" during the most important hour of the incident.
Why recovery from a cascading failure is slow
The thundering herd on restored servers
The most telling line in Microsoft's updates was that restored servers could become unresponsive again once they received traffic, and that Microsoft limited which traffic could reach them. This is the second half of the cascading failure problem, and it is why these outages last hours instead of minutes.
When you bring a cold server back into a fleet that is already overloaded, the load balancer happily gives it a full share of traffic immediately. Clients that have been retrying for an hour pounce on it. Every one of those clients needs a fresh secure connection, which is exactly the expensive operation that tipped the fleet over in the first place. The restored server melts, fails its health check, and is removed again. Operators watch the healthy count go up and then back down, which is demoralising and easy to misread as "the fix did not work".
What a controlled recovery looks like
Microsoft's reported mitigations map to the standard playbook for this situation, and they are worth copying into your own runbooks:
- Freeze changes. Microsoft paused all deployments and configuration changes. During a capacity spiral, the last thing you want is an unrelated release taking more nodes out for a rolling restart.
- Stop the removals. Microsoft said it took steps to prevent more servers being removed from service. A floor on how much of a pool a health checker may remove is one of the most effective guardrails you can add.
- Change the health check. Microsoft tested bypassing the component that processed health checks, and used an alternative health check method to return a subset of servers to service. If your health check is served by the same overloaded path, it measures overload, not health.
- Admit traffic gradually. Limiting which traffic reaches restored servers is a form of slow start. Ramp new capacity in steps and watch it hold before adding more.
- Roll back suspected changes. Reverting the correlated network change is the classic "undo first, debug later" move.
None of these require heroics. All of them are much easier if they were designed in before the incident, and much harder if someone has to invent them at 2 a.m. while a status page is getting angrier by the hour.
Lessons for your own systems
Design health checks that do not lie under load
A health check has one job: tell the load balancer whether this node can usefully serve traffic. In practice, many health checks fail that job in one of two ways. Shallow checks (a static 200 from a separate thread) say "healthy" even when the real request path is broken. Deep checks (which call every dependency) say "unhealthy" whenever any dependency hiccups, which means a shared dependency failure removes your whole fleet at once.
Practical rules that reduce the risk of a health check driven spiral:
- Serve health checks from a path that is cheap and has reserved capacity, so a node under heavy load can still answer honestly.
- Separate liveness ("the process is running") from readiness ("this node should get traffic"). Restart on liveness failure, drain on readiness failure.
- Do not fail readiness because a shared downstream dependency is down. Every node will fail at once, and removing them all makes things worse, not better.
- Require several consecutive failures before removal, and a few consecutive passes before re-admission.
- Set a maximum percentage of a pool that automation may remove. Beyond that floor, alert a human instead of removing more.
Protect expensive operations with load shedding
Microsoft's wording pointed at the secure connection setup process becoming overwhelmed. Whether or not that turns out to be the root cause, it highlights a general lesson: the most expensive operation in your request path is where overload shows up first. For many services that is TLS handshakes, database connection setup, or authentication token validation.
Give those operations explicit concurrency limits. When the limit is reached, reject quickly with a clear retryable error rather than queueing until timeouts fire. A fast rejection costs almost nothing. A slow timeout holds a connection, a thread and memory, and makes the node look dead to its health check. Session resumption and long-lived connections also help, because they reduce how often clients need a full handshake.
Make retries polite
Clients make cascading failures worse. Every client that retries immediately, without backoff, multiplies the load on the survivors. If you own clients (internal services, SDKs, mobile apps), make sure they honour Retry-After headers, use exponential backoff with jitter, cap the number of attempts, and use a retry budget so that retries never exceed a small fraction of total requests. If you call Microsoft Graph or any other large SaaS API from your own systems, the same rules apply on the way out. During this outage, Power Platform flows and AI assistant connectors that depended on Microsoft Graph were reported to fail intermittently, and aggressive retries from automation would only have added to the pile.
Alert on capacity, not just on errors
Add these signals to your paging rules if they are not there already:
- Healthy instance count per pool, with an alert on a sudden percentage drop.
- Load per healthy instance (demand divided by healthy capacity), not just total load.
- Health check failure rate across the pool. One node failing is noise. Twenty failing in a minute is a spiral starting.
- CPU on connection setup or authentication paths, where available.
These signals tend to fire before customers notice, which is exactly when an on-call engineer can still freeze changes and stop removals cheaply. If you are routing these alerts today to an email inbox, November 12 is a good reason to reconsider. Pagerly's on-call paging sends alerts to the person on shift in Slack and escalates if nobody acknowledges.
Lessons for your incident response process
Your communication stack is a dependency
For companies that run on Microsoft 365, the hardest part of November 12 was not technical. It was coordination. Email was down, calendar invites failed, and anyone whose on-call schedule lived in an Outlook calendar could not easily check who was supposed to respond. We wrote about this class of problem after an earlier Exchange Online authentication incident in our post on the identity provider outage blast radius, and more broadly in when your incident response tooling is the outage. The short version: the tools you respond with should not share a single point of failure with the tools you respond to.
Questions worth answering this week, while the incident is fresh:
- If our email and calendar provider is down for ten hours, how does the on-call engineer find out they are on call?
- How do we page someone if the paging path relies on email delivery?
- Where do we post customer updates if our status page sign-in or our support inbox depends on the affected provider?
- Is there a second chat or phone channel that everyone on the incident roster already has, and has it been tested?
Separate "our outage" from "their outage" early
When a provider as central as Microsoft 365 goes down, every internal team starts reporting problems at once. Help desk tickets spike, sales cannot reach customers, and product teams wonder if their own service is broken. The incident commander's first job is to establish quickly which symptoms are caused by the provider and which might be your own. A simple pattern helps:
- Open one internal incident for the provider outage, with a single owner and a single channel.
- Check the provider's official status page and incident IDs (here, EX1550543 and MO1550821) and link them in the channel.
- Ask every team reporting a problem to post it in that channel, so you can spot symptoms that do not fit the provider's stated scope.
- Open a separate incident only for issues that cannot be explained by the provider.
This avoids two failure modes: ten parallel incidents for the same root cause, and a real internal issue hiding under the noise of a big external one.
Communicate with your own customers
Even if your product has nothing to do with email, your customers may assume you are affected, or you may be affected in ways they will notice: delayed notification emails, failed calendar invites from your app, broken SSO if your identity setup touches the provider. A short status update that says what is affected, what is not, and links to the provider's status saves your support team a lot of repetitive replies. A hosted status page such as Pagerly's status pages makes that a two minute task instead of a scramble, as long as publishing does not depend on the provider that is down.
Do not loosen security under pressure
During long outages, someone always proposes a shortcut: disable the conditional access policy, forward mail to personal accounts, share a password so a colleague can try from another device. Microsoft said there was no indication of malicious activity in this incident, but attackers watch outage news too, and phishing that imitates "restore your mailbox" messages is a predictable follow-on. Keep the security baseline intact and tell people explicitly that IT will never ask them to reset passwords or reinstall clients to fix a provider outage.
A post-incident checklist for on-call teams
You do not need to wait for Microsoft's review to learn from this. Here is a short checklist to run through with your team, whether or not you were directly affected:
- Health checks: List every load balancer and orchestrator health check in production. For each, write down what it actually tests and whether it can fail for every node at once.
- Removal floors: Confirm there is a cap on how much of each pool can be removed automatically, and that hitting the cap pages a human.
- Capacity signals: Add healthy instance count and load per healthy instance to your dashboards and alerts.
- Load shedding: Identify the most expensive operation in your main request path and add a concurrency limit with fast rejection.
- Slow start: Check that your load balancer ramps traffic gradually to new or restored instances.
- Change visibility: Make sure network and infrastructure changes appear on the same timeline as application deploys.
- Change freeze: Document who can declare a deploy freeze during an incident and how it is enforced.
- Out of band contact: Verify the on-call roster can be reached and can see the current schedule without your primary email and calendar provider.
- Customer comms: Pre-write a status update template for "a major provider we depend on is down" so it can go out in minutes.
- Game day: Run a short drill where a third of a non-critical pool disappears, and watch whether automation helps or makes it worse.
How a Slack-native on-call setup helps in an outage like this
No tool prevents a cascading failure in someone else's infrastructure. What a good on-call setup does is keep your response working while the provider recovers. For teams whose daily communication already runs through Slack, keeping the schedule, the pages and the incident channel in Slack means a Microsoft 365 outage does not also take out your ability to find and reach the responder. Pagerly runs on-call rotations, paging, escalation and incident channels inside Slack, so the "who is on call right now" answer is a mention away rather than an Outlook calendar lookup. If your organisation lives in Microsoft Teams instead, the lesson still holds: make sure your on-call schedule and paging path do not depend on the same Exchange Online services that failed on November 12.
That is a design choice, not a product feature. Whatever tools you use, map which of them share a provider, and make sure at least one way of reaching the person on call survives a long outage of your main email and calendar platform.
Conclusion
The November 12 Microsoft 365 outage will get a formal root cause soon, and it may turn out to be the network configuration change Microsoft rolled back, or something else entirely. The specific trigger matters less than the shape of the failure. Servers became unavailable, survivors absorbed their load without any rise in traffic, an expensive connection setup process saturated, health checks removed more nodes, and restored servers fell over again as soon as traffic found them. That shape exists in nearly every horizontally scaled service.
The practical response is unglamorous: honest health checks, floors on automated removal, load shedding on expensive paths, polite retries, slow start for restored capacity, capacity alerts that watch supply as well as demand, and an incident process that does not rely on the provider that just went down. Teams that put those in place before the next big outage will spend it calmly watching graphs recover. Teams that do not will spend it rediscovering the same lessons Microsoft's engineers worked through on November 12.
