Incident Library

IL-0263 GitHub · 2012-11-30networking

GitHub was slow and erroring all day and down for 18 minutes as links between access and aggregation switches saturated

GitHub's switches had been connected each to the switches in neighbouring racks, so traffic across the network passed through every switch in between, saturating the links in the middle of the chain. Actions that should take under a millisecond had been taking several times that long, with spikes of hundreds of times. To fix this GitHub bought aggregation switches for a tree topology in which access switches in each cabinet connect directly to the aggregation switches. Each server is connected to two redundant switches, A and B, so the plan was to disconnect, reconfigure and reconnect the B switches first, which was done on Thursday 29 November with only small hiccups, and the A switches on Friday morning.

Connecting the last A switch caused a bridge loop from a misconfiguration on that switch pair, and the switches disabled links; GitHub fixed it quickly and completed the migration. The links between access and aggregation switches were then saturated, which GitHub took to be a broadcast storm from an undetected loop. While hunting for it by disconnecting single links, GitHub found that a setting meant to detect partial link failure, by checking that both transmit and receive work, is not supported between its aggregation and access switch models: shutting down one link made this watchdog trigger falsely and disable all the links, and losing several switches at once during this troubleshooting caused the 18 minutes of downtime. With the vendor's help the setting was removed, after which any single switch could be removed without affecting servers.

Still unable to find a loop, GitHub escalated again to the network vendor, which raised the case to its highest severity. Five hours of troubleshooting on Friday night found a bug in the aggregation switches: they could not learn a large share of MAC addresses and flooded frames for those addresses to all ports, saturating the access-to-aggregation links. In a maintenance window on Saturday morning at 0600 Pacific, GitHub restarted some core processes on the aggregation switches so they could learn MAC addresses again, and traffic and performance returned to normal. The vendor found the root cause of the MAC learning issue from GitHub's diagnostic data and was expected to ship a fix.

Severity
–
Scope
GitHub: 18 minutes of complete unavailability and sporadic slow responses and intermittent errors for the whole day; one fileserver pair offline for a large part of the day
Users affected
all GitHub users during the 18 minutes of downtime; a small percentage of repositories on the offline fileserver pair
Region
–
Time to detect
–
Time to resolve
–

Symptoms

On Friday, 30 November 2012, GitHub had sporadic bursts of slow responses and intermittent errors for the whole day and was completely unavailable for 18 minutes. One fileserver pair was offline for a large part of the day, which affected a small percentage of repositories; this was a side effect of the network problems on the high-availability clustering between the fileserver nodes.

The problems began during a planned migration of the datacenter switches to a new aggregation network. When the final A switch was connected, GitHub lost connectivity with the B switch in the same cabinet: a misconfiguration on that pair of switches had caused a "bridge loop", and the switches disabled links to protect the network. After that was fixed and the migration completed, performance stayed below expectations, and all of the connections between the access switches and the aggregation switches were completely saturated.

Engineers diagnosed the saturation as a "broadcast storm" from a bridge loop that had gone undetected, and spent most of the day auditing switch configurations port by port. While disconnecting single access-to-aggregation links to narrow the problem down, they found that taking down one link of a redundant pair made the access switch disable its redundant link too, so the network could not survive the loss of an aggregation switch. With the switch vendor they found the cause: a setting meant to detect partial link failure is not supported between the aggregation and access switch models, and shutting down one link made it falsely disable all the links. The 18 minutes of hard downtime happened during this troubleshooting, when connectivity to several switches was lost at the same time. After that setting was removed, a couple more hours of testing links found no loop.

The cause turned out to be different. In a five-hour investigation with the switch vendor on Friday night, GitHub found that the aggregation switches were missing many MAC addresses from their MAC address tables and could not learn a significant share of them, so they flooded traffic for those devices to every port. That flooded traffic was enough to saturate all of the links between the access and aggregation switches.

Symptom High latencyHigh error rateService outage

Root cause

Trigger
On the morning of 30 November GitHub moved the A switches in its server cabinets onto the new aggregation switches, the second half of a migration whose B-switch half had been done the day before.

Detection

Engineers saw the problems during the maintenance itself: connectivity to the B switch was lost as the last A switch was connected, and afterwards performance stayed low and the links between access and aggregation switches showed as completely saturated.

Remediation

Action items

Lessons

GitHub had designed the maintenance to have no impact on customers and clearly failed, so it plans to invest in a staging copy of its network to test such changes and catch bugs like this one. During the response the team fixated for a long time on a bridge loop, which kept it from considering other causes. GitHub had a very positive experience with the vendor's support staff, so it will contact that support team at the first sign of network trouble.

Sources

Related cases

Check your cluster for this

kubegap audits a Kubernetes cluster for conditions like the ones in this case, Network switch, NIC, cable and switch port link among them, read-only, from Claude Code or Codex. Its checks cite public reports like this one.

For AI tools and scripts

The API needs no key. The MCP server offers search_incidents, get_incident, list_incidents, get_topic and vocab; both are explained on API and MCP.