INCIDENT REPLAY · 2023-01-25
Microsoft WAN: an IP change made every WAN router recompute
A command during an IP change made every WAN router recompute at once. The end state was fine.
A reconstruction, not the operator's network. Hammerhead's authors rebuilt the change from the public record as a small network of their own. No configuration here is the operator's. What follows is what the tool reported on that reconstruction; it is not a claim that the tool would have prevented the outage.
What happened
The summary at the top is Hammerhead's own one-line description of the replay; the sources below are the record. Hammerhead's catalog rates its confidence in this account high.
Sources
- https://azure.status.microsoft/en-us/status/history/
- https://web.archive.org/web/20230401170007/https://azure.status.microsoft/en-us/status/history/
- https://status.azure.com/en-us/status/history/
- https://web.archive.org/web/20230130132357/https://status.azure.com/en-us/status/history/
- https://www.bleepingcomputer.com/news/microsoft/massive-microsoft-365-outage-caused-by-wan-router-ip-change/
- https://www.networkworld.com/article/971873/global-microsoft-cloud-service-outage-traced-to-rapid-bgp-router-updates.html
- https://www.rfc-editor.org/rfc/rfc4456.txt
- https://www.juniper.net/documentation/en_US/junos12.1x47/topics/reference/command-summary/clear-ospf-ospf3-database.html
- https://www.arista.com/en/um-eos/eos-is-is
- https://web.archive.org/web/20241213063725/https://www.arista.com/en/um-eos/eos-is-is
What the public record says
Scope and timeline
- 1. PIR, What happened?: "Between 07:08 UTC and 12:43 UTC on 25 January 2023, customers experienced issues with network connectivity, manifesting as long network latency and/or timeouts when attempting to connect to resources hosted in Azure regions, as well as other Microsoft services including Microsoft 365 and Power Platform." It "also impacted Azure Government cloud services that were dependent on Azure public cloud." (PRE gave the start as 07:05 UTC.)
- 2. PIR: "While most regions and services had recovered by 09:05 UTC, intermittent packet loss issues caused some customers to continue seeing connectivity issues due to two routers not being able to recover automatically. All issues were fully mitigated by 12:43 UTC."
- 3. Traffic affected, PIR: "to/from the Internet, Inter-Region traffic, Cross-premises traffic via ExpressRoute or VPN/vWAN and US Gov Cloud services using commercial/public cloud services."
- 4. Services named by BC as affected: Microsoft Teams, Exchange Online, Outlook, SharePoint Online, OneDrive for Business, Power BI, Microsoft 365 Admin Center, Microsoft Graph, Microsoft Intune, Microsoft Defender for Cloud Apps and Microsoft Defender for Identity.
The change
- 5. PRE described it as an address change: "As part of a planned change to update the IP address on a WAN router, a command given to the router caused it to send messages to all other routers in the WAN, which resulted in all of them recomputing their adjacency and forwarding tables. During this re-computation process, the routers were unable to correctly forward packets traversing them."
- 6. PIR is more specific. "At 07:08 UTC a network engineer was performing an operational task to add network capacity to the global Wide Area Network (WAN) in Madrid. The task included steps to modify the IP address for each new router, and integration into the IGP (Interior Gateway Protocol, a protocol used for connecting all the routers within Microsoft's WAN) and BGP (Border Gateway Protocol, a protocol used for distributing Internet routing information into Microsoft's WAN) routing domains."
- 7. The record names the protocols only as "IGP" and "BGP". It does not say which IGP.
The command
- 8. PIR: "This change added a command to purge the IGP database – however, the command operates differently based on router manufacturer. Routers from two of our manufacturers limit execution to the local router, while those from a third manufacturer execute across all IGP joined routers, ordering them all to recompute their IGP topology databases."
- 9. PRE: "The command that caused the issue has different behaviors on different network devices, and the command had not been vetted using our full qualification process on the router on which it was executed."
- 10. Three router manufacturers are in the WAN (fact 8, and the repair item in fact 19: "across all three vendors for all WAN router roles"). None is named.
- 11. The command was not on the block list. PIR: "Microsoft has a real-time Authentication, Authorization, and Accounting (AAA) system that must approve each command run on each router, including a list of blocked commands that have global impact", but "the command's different, global, default action on the router platform being changed was not discovered during the high-impact commands evaluation for this router model and, therefore, had not been added to the block list."
The process
- 12. PIR: the standard operating procedure "follows a 4-step process that involves: [1] testing in our Open Network Emulator (ONE) environment for change validation; [2] testing in the lab environment; [3] a Safe-Fly Review documenting steps 1 and 2, as well as a roll-out and roll-back plans; and [4] Safe-Deployment which allows access to only one device at a time, to limit impact."
- 13. PIR: "In this instance, the SOP was changed prior to the scheduled event, to address issues experienced in previous executions of the SOP. Critically, our process was not followed as the change was not re-tested and did not include proper post-checks per steps 1-4 above."
The failure
- 14. It was not a wrong end state. PIR: "even though the engineer only had access to a single router, it was still connected to the rest of the Microsoft WAN via the IGP protocol. Therefore, the change resulted in two cascading events. First, routers within the Microsoft global network started recomputing IP connectivity throughout the entire internal network. Second, because of the first event, BGP routers started to readvertise and validate prefixes that we receive from the Internet. Due to the scale of the network, it took approximately 1 hour and 40 minutes for the network to restore connectivity to every prefix."
- 15. The network recovered by itself. PIR: "During the time it took for routing to automatically converge, customer impact dynamically changed as the network completed its convergence." PRE: "By 08:10 UTC, the network started to recover automatically."
- 16. It happened twice. PIR: "Issues in the WAN were detected by monitoring and alerts to the on-call engineers were generated within 5 minutes of the command being run. However, the engineer making changes was not informed due to the unqualified changes to the SOP. Due to this, the same operation was performed again on the second Madrid router 33 mins after the first change, thus creating two waves of connectivity issues".
- 17. The tail. PIR: "our automated systems for maintaining the health of the WAN were paused, including the systems for identifying and removing unhealthy devices and the traffic engineering system for optimizing the flow of data across the network. Due to the pause in these systems, some paths in the network were not fully optimized and, therefore, experienced increased packet loss from 09:25 UTC until those systems were manually restarted".
- 18. What it looked like from outside. NW, reporting ThousandEyes: "Multiple Microsoft BGP prefixes were withdrawn completely and then almost immediately readvertised", and "These re-advertisements repeated several times, causing significant route-table instability."
What Microsoft changed afterwards
- 19. PIR names two contributing factors: "A change was made to a standard operating procedure that was not properly revalidated and left the procedure containing an error and without proper pre- and post- checks." and "A standard command that has different behaviors on different router models was issued outside of standard procedure that caused all WAN routers in the IGP domain to recompute reachability." Repair items include: "Audit and block similar commands that can have widespread impact across all three vendors for all WAN router roles", and "Publish real-time visibility of approved-automated and approved-break glass, as well as unqualified device activity".
- 20. None of the repair items is a configuration check. They are a command block list, change visibility, training, and review of procedures.
What the reconstruction assumed
Decided by Hammerhead's authors to build a network that runs. None of it describes the operator's network.
None of the following is on the public record. Each is a choice we made so that the corpus parses, converges and runs in seconds. If one of them is wrong, the replay is wrong in that respect.
- A1. The real incident was not a wrong end state, and this corpus cannot contain it. Facts 8, 14 and 15: an operational command (not a configuration line) made every router in the IGP domain recompute, the network was impaired while it reconverged, and it then recovered with no configuration change. A pair of config snapshots has nowhere to put a command, a router model's interpretation of it, or a recomputation in progress. What we CAN express in config terms is the planned change the command was part of (facts 5 and 6: an IP address change on a WAN router), done right and done wrong. Those are the candidates below. The "done wrong" candidates are our invention. Nothing on the record says Microsoft's address change was itself incorrect.
- A2. The change is a renumbering of an existing router. Fact 6 says the routers were new and being integrated. We model an in-service router because a router that carries no traffic yet has nothing to lose, and the brief for this replay is the address change. Two forms, each with an intended and a botched candidate:
- Pair 1, a core link. The wan-par-1 to wan-mad-1 link moves from 10.0.0.12/31 to 10.0.0.112/31. after_intended/ renumbers both ends. after_botched/ renumbers only wan-mad-1's end, so the two ends are in different subnets and the OSPF adjacency cannot form. - Pair 2, a loopback. wan-mad-1 Loopback0 moves from 10.255.0.5 to 10.255.0.65, and its OSPF and BGP router-ids with it. after_intended_loopback/ also updates every reference on other routers: both route reflectors' neighbor statements, both reflectors' BGP-protection ACL entries, and a static route on wan-mad-2 whose next hop is the loopback. after_botched_loopback/ updates wan-mad-1's own file and nothing else, as if the peer-side steps of the procedure were skipped.
- A3. Vendor and syntax. Three unnamed manufacturers (fact 10). Every device here is Cisco IOS syntax, because that is where this parser classifies the most of what such a router carries. This says nothing about what Microsoft runs, and a single-vendor corpus cannot represent the thing that mattered on the day, which was a difference between vendors.
- A4. The IGP is OSPF because the model could not run iBGP over IS-IS. The record says "IGP" (fact 7). We first built the WAN on IS-IS level 2. The simulator then refused all 13 iBGP sessions, because its BGP stage checked peer reachability against OSPF results only (
RESULT.md, section 6.1). That snapshot is kept asprobes/before_isis/. The committed corpus uses OSPF area 0 so that the replay ran at all. This is a limit of the tool that changed the corpus, so we say so here rather than leave OSPF looking like a free choice. The limit (G5) was fixed in PR #86 (60df365):probes/before_isisnow establishes its 13 iBGP sessions. The corpus was not rebuilt on IS-IS, so every recorded result still describes the OSPF WAN. - A5. Topology. Madrid and two Madrid routers are on the record (facts 6 and 16). Everything else is ours: eight WAN routers in one AS (
wan-lon-1,wan-ams-1,wan-fra-1,wan-par-1,wan-mad-1,wan-mad-2,wan-dub-1,wan-nyc-1), eleven /31 core links with the metrics ingen_corpus.py, and four regional sites (site-fra-1,site-dub-1,site-mad-1,site-nyc-1), each its own AS with eBGP to one or two WAN routers.site-mad-1is dual-homed to both Madrid routers. The real WAN has thousands of routers ("Due to the scale of the network", fact 14); the public record shows none of its shape. - A6. BGP layout. iBGP between loopbacks with two route reflectors (
wan-lon-1,wan-ams-1); every other WAN router is a client of both and setsnext-hop-self. The reflectors carry no site and do not setnext-hop-self: with it, the model rewrites the next hop of reflected routes and reports a forwarding loop that IOS would not have (RESULT.md, section 6.2;probes/rr_next_hop_self/). All AS numbers are private-use;65010is the WAN. Microsoft's real AS is not used. - A7. Addresses.
10.255.0.0/24loopbacks,10.0.0.0/24core links,172.20.0.0/24site links,10.101.0.0/16to10.104.0.0/16site prefixes,10.250.5.0/24a Madrid telemetry LAN. All RFC 1918. The telemetry LAN, the static route onwan-mad-2that reaches it throughwan-mad-1's loopback, and the reflectors'BGP-PEERS-INACL exist so that the corpus contains the three kinds of reference a loopback renumbering has to chase (a BGPneighborstatement, a static next hop, an ACL host entry). They are plausible, and they are ours. - A8. Lines left out so that parse coverage is 100%. A production config would carry these, and this parser does not classify them on IOS:
isis network point-to-point,ip ospf network point-to-point,ip ospf hello-interval,ip ospf dead-interval,timers throttle spf,max-metric router-lsa on-startup,set-overload-bit on-startup,spf-interval,log-adjacency-changes(under OSPF),bgp cluster-id,no bgp default ipv4-unicast,address-family ipv4(accepted only when spelledaddress-family ipv4 unicast) withneighbor ... activateunder it,mtu,mpls ip,load-interval,no ip redirects,no ip proxy-arp, and the management plane (version,service ...,ip cef,snmp-server,logging host,ntp server,line vty,access-class). We left them out rather than carry unparsed lines. Note which ones they are: every knob that governs how fast and how gracefully a router reconverges is in that list. - A9. Timing, flooding and recomputation are not modeled at all. The simulator computes converged routing state. It has no clock, no LSA or LSP flooding, no SPF scheduling, no BGP update churn, and no notion of a router being unable to forward while it recomputes (facts 5, 14, 15, 18).
- A10. The command and the vendor, for `COMMANDS.md`. Microsoft names neither (facts 8 and 10); it says only that the command purges the IGP database, is local on two vendors and orders every IGP-joined router to recompute on the third. For the operational-command rows we ASSUME the command was Junos
clear ospf database purgeon a Juniperwan-mad-1. It is chosen because it is one of the two IGP purges we found a vendor documenting as flooded to the other routers, and the only one for OSPF, which is the IGP this corpus runs (A4): JUNOS says "All link-state advertisements are set to MAXAGE and are flooded. The database is repopulated when the originators of the link-state advertisements receive the MAXAGE link-state advertisements and reissue them", and warns that it "causes significant network disruption". How far a flooded LSA travels is the protocol's to say: RFC 2328 12.1.3 floods every type but AS-external LSAs "throughout a single area only", so the check reads the purge as reaching the routers inwan-mad-1's areas, which in this one-area corpus is every WAN router. (The other is Arista EOSclear isis database, which EOS says "sends purge LSPs throughout the network to clear LSPs from all devices", and RFC 6232 floods "throughout an area"; using it would have meant an IS-IS corpus.) Thepurgeoption is on the Junos 12.x and 13.2 pages and no longer on the current one. Nothing on the record says Microsoft runs Juniper, or that this is the command.tests/gauntlet/microsoft_wan_2023/ multivendor/is the WAN ofbefore/andafter_intended/withwan-mad-1written in Junos syntax; to parse it, the site link is a passive OSPF interface instead of the reflector sessions settingnext-hop-self(the Junos parser reads nothen next-hop self), and the site ACL is a firewall filter. Every other router is unchanged.
What Hammerhead said
Each run below is pinned by Hammerhead's replay tests at commit 0ee9732: the verdict and the quoted text are checked against the tool's output, and a run that disagrees fails the test. Reason lines are copied verbatim; a pinned line can be part of a longer reason. Every preflight run uses --max-blast-radius 100, so a change is never counted as caught merely because it touched many devices of a small network.
Hammerhead's own first-versus-now record
- First verdict
- Correct renumbering:
pass. Botched (one end of a link):pass, no caveat. - Verdict now
- Botched:
fail, "OSPF wan-mad-1 <-> wan-par-1" lost. Correct:pass, and the text now says the verdict covers the converged end state only. The potential-microloop check finds none in the correct renumbering (stillpasswith--fail-on-transient-loops) and three in the botched one. - Fixed?
- Yes, for the command, as reconstructed (vendor and command assumed). With the command listed (
--commands): on a Junoswan-mad-1,clear ospf database purgeisfail, "It reaches 8 router(s), OSPF area 0 ... BGP on 8 router(s) ... resolves next hops over this IGP" (the corpus is one area, so that is every WAN router); the same command on the router written as Cisco IOS isunknown, "has not been vetted on cisco_ios" (COMMANDS.md). No timing: how long the storm lasted is outside the model, and it is not an ordering of two FIBs either, which is all the microloop check reads. Its nearest config mistake is caught too: a lost adjacency with no lost flow is gated.
Quoted from docs/replays/README.md. “First” is the tool before the fixes this replay prompted.
the IGP purge on a Junos wan-mad-1, during the planned renumbering
now: failOn the reconstruction, hammerhead preflight on a before and an after snapshot with --commands @microsoft_wan_2023/commands/purge_on_madrid.yaml returned fail, for the reasons below.
Reason text pinned (some reason contains each line)
- command "clear ospf database purge" on wan-mad-1 (junos): sets every LSA in its database to MaxAge and floods it
- the flooding scope is the protocol's, each of its areas, and AS-external LSAs further, which the reach listed does not include
- It reaches 8 router(s), OSPF area 0: wan-ams-1, wan-dub-1, wan-fra-1, wan-lon-1, wan-mad-1 (+3 more)
- BGP on 8 router(s) (wan-ams-1, wan-dub-1, wan-fra-1, wan-lon-1, wan-mad-1 (+3 more)) resolves next hops over this IGP
- [catalog junos.ospf.database-purge]
Pinned in tests/gauntlet/replays-commands.yaml.
the same purge, waived with --allow-command-impact
now: passOn the reconstruction, hammerhead preflight on a before and an after snapshot with --commands @microsoft_wan_2023/commands/purge_on_madrid.yaml --allow-command-impact returned pass.
Caveats pinned (some caveat contains each line; a caveat never moves the verdict)
- command "clear ospf database purge" on wan-mad-1 (junos): sets every LSA in its database to MaxAge and floods it
Pinned in tests/gauntlet/replays-commands.yaml.
the same purge on wan-mad-1 written as Cisco IOS: not vetted on that platform
now: unknownOn the reconstruction, hammerhead preflight on a before and an after snapshot with --commands @microsoft_wan_2023/commands/purge_on_madrid.yaml returned unknown.
Blockers pinned (some blocker contains each line)
- "blocker":"operational_command_unvetted"
- "device":"wan-mad-1"
- "vendor":"cisco_ios"
- "command":"clear ospf database purge"
- "reason":"the catalog has no entry for `clear ospf database purge` on cisco_ios"
Pinned in tests/gauntlet/replays-commands.yaml.
a read on the Junos wan-mad-1 (control)
now: passOn the reconstruction, hammerhead preflight on a before and an after snapshot with --commands @microsoft_wan_2023/commands/show_on_madrid.yaml returned pass.
Text no reason may contain
- show ospf neighbor
Pinned in tests/gauntlet/replays-commands.yaml.
renumbering, botched (potential microloop)
now: failOn the reconstruction, hammerhead preflight on a before and an after snapshot returned fail.
This run repeats another pinned run (same snapshots, flags and verdict) to record the potential microloops it finds. A caveat never moves the verdict.
Caveats pinned (some caveat contains each line; a caveat never moves the verdict)
- wan-ams-1 -> wan-lon-1 -> wan-ams-1, if wan-lon-1 has its new next hop while wan-ams-1 still has its old one
- wan-mad-1 -> wan-mad-2 -> wan-mad-1, if wan-mad-1 has its new next hop while wan-mad-2 still has its old one
Pinned in tests/gauntlet/replays-transients.yaml.
What changed in Hammerhead because of it
From the “What was fixed” table in Hammerhead's replay notes, where each fix landed after a failing test. “Found by” is copied as written; a family name means the batch this incident belongs to.
Adjacency-loss gate (--allow-adjacency-loss)
A lost OSPF adjacency or BGP session with a second path loses no flow and used to pass silently.
Found by: Microsoft
PASS states its scope in text
"The converged end state only" was in the JSON ledger and nowhere an operator would read it.
Found by: Microsoft
Potential microloops (--fail-on-transient-loops to gate)
A steady-state verdict said nothing about the way from one FIB to the other. A cycle in the union of the before and after next-hop graphs that neither state has is named, with an update order that avoids it. A caveat by default; it does not see the Microsoft outage itself.
Found by: Microsoft WAN
Operational commands (--commands, --allow-command-impact)
A command is in no configuration, so the one replay whose cause was a command could not be caught. A change now lists the exec commands it runs; each is looked up in a catalog whose entries all rest on the vendor's own documentation or an RFC, and its reach (OSPF area or domain, IS-IS level, BGP sessions, the BGP speakers over that IGP) is read from the snapshot. Beyond its device it fails; not in the catalog for that vendor it is unknown.
Found by: Microsoft WAN
Limits
- The configurations are a reconstruction. Where the record is silent, the assumptions above fill the gap; if one is wrong, the replay is wrong in that respect.
- A verdict describes the reconstructed network's converged state. Timing, traffic load, and anything a device does that no configuration states, such as software reacting to a health check or a firmware bug, are outside it.
- A pass is reported as a pass. A fail says a gate fired on the reconstruction, nothing more.
Not fixed: Transient behaviour during reconvergence, other than potential microloops
Timing, intermediate per-router states, BGP withdrawal races, path hunting and SPF throttling need event timing no config contains. Ordering-induced blackholes are computable and not built. Stated on every PASS. The operational-command check says which routers a command reaches, never how long they take to recompute.
Recorded against: Microsoft
Not fixed: An exec command not in the catalog, or not listed
A command is judged only when the change lists it (--commands); there is no playbook reader yet. A command with no sourced catalog entry for its vendor is unknown, never guessed: several families are not catalogued because no vendor page states their reach (IOS clear isis, clear ip route, a generic show on IOS-XR, EOS and FRR).
Recorded against: Microsoft
Imported from docs/replays/microsoft-wan-2023/FACTS.md and the replay manifests in the Hammerhead repository at commit 0ee9732.