IL-0515 Python Software Foundation · 2026-08-15networking
Downloads from files.pythonhosted.org failed with intermittent 502 and 503 errors for two weeks, breaking PyPI installs
files.pythonhosted.org is a Fastly CDN service in front of three origins. Uploaded files are written to Amazon S3 as the durable copy and synced to Backblaze B2; on downloads Fastly tries B2 first and falls back to S3 when B2 does not answer or answers unexpectedly, and a third backend, Conveyor, serves everything that is not a package file. From 15 August 2026, a partial rollback in a Fastly canary deployment left one Seattle-area cache node with reverted caching configuration behind routing configuration that had not been reverted, and the routing layer returned 502 for traffic reaching that node. On 19 August Fastly's network operations removed a routing override that sent part of PyPI's traffic to the affected point of presence, Fastly saw recovery there on 20 August, and on 28 August Fastly patched the canary configuration bug and removed all PSF traffic, including PyPI, from its canary cohort.
While investigating, PyPI's infrastructure engineer found older bugs in PyPI's own Fastly configuration that produced the same symptom. The fallback to S3 ran only when B2 answered with an error status; when B2 did not answer at all, Fastly synthesized its own 503 and skipped the fallback, until infra#237 added that path on 18 August. Segmented caching, used so a Range request does not pull a whole gigabyte-sized wheel into cache, cannot answer a suffix range such as bytes=-1024 or a range that starts past the end and returns a synthetic 501, and some installers read wheel metadata with suffix ranges; infra#241 on 21 August and infra#243 on 24 August exempted those requests, the second after two broken parallel downloaders generated 41,315 more errors of that class in a single day. infra#245 on 28 August moved an exemption check after URL normalization: a .metadata request with a query string had kept segmented caching on, got a 501 from the archive backend, and that response was cached and served to every later request for the same file.
After infra#241, the 5xx count fell to two to three orders of magnitude below the pre-incident baseline, so part of what had been treated as background noise had been this bug. Downloads were fully working again from 28 August.
- Severity
- –
- Scope
- Downloads from files.pythonhosted.org and therefore installations from PyPI
- Users affected
- some PyPI users
- Region
- Seattle-area Fastly point of presence for the Fastly fault
- Time to detect
- 2d
- Time to resolve
- 13d
Symptoms
For about two weeks in August 2026, some PyPI users got intermittent 502 and 503 errors when downloading files from files.pythonhosted.org, and installations from PyPI failed. The first two reports of persistent 502s were opened in the support tracker on 17 August.
A report on 18 August reproduced the problem in detail: 88 recorded 502s over six hours across 32 unrelated packages, including the small .whl.metadata range requests installers use to read PEP 658 metadata. A report on 19 August traced the failures to one Fastly cache node, cache-pae2080020, which had returned 502 for every request routed to it for over 19 hours; the x-served-by headers on the failing responses confirmed it.
On the PyPI side the errors were hard to see. Datadog Logs showed nothing of consequence for the PyPI Files errors at first, and the 5xx baseline was already thousands to tens of thousands of responses, so the increase from 15 August was easy to miss. Fastly's real-time analytics showed B2 errors climbing from 15 August while the S3 archive backend stayed flat at zero, because the fallback was not firing. On 21 August a single client sending logically invalid ranges pushed the count close to a million, and some requests got 501 responses that looked like 502s from outside.
Symptom High error rate
Root cause
Root cause Dependency failure
- Trigger
- A partial rollback during a canary deployment inside Fastly's network, whose canary cohort had included PyPI's traffic for a number of years, left the caching configuration of one Seattle point of presence reverted while the routing configuration in front of it was not.
Detection
Users filed reports in the PyPI support tracker; one report isolated the 502s to a single Fastly cache node using the x-served-by headers of the failing responses.
Remediation
- Fastly's network operations removed the routing override that sent part of PyPI's traffic to the affected point of presence
- Fixed the B2-to-S3 fallback for the case where B2 does not respond at all (infra#237)
- Exempted suffix and multi-range requests from segmented caching (infra#241, infra#243)
- Fastly patched the canary configuration bug and removed all PSF traffic from its canary cohort
- Moved the segmented-caching exemption check after URL normalization (infra#245)
Action items
- Improve the logging configuration of the file hosting service (infra#238)
- Reject HTTP methods that a file host should not receive (infra#239)
- Follow a support ticket with Fastly about segmented-caching range handling, and revert PyPI's own handling code once Fastly fixes it
- Return to Fastly's canary program once clearer controls and notifications exist around that traffic
- Hire an infrastructure engineer, partly for PyPI, to catch conditions like this earlier
Lessons
None of the PyPI configuration bugs were new; they had been in the configuration for a while and came out only when real traffic on large files with range requests forced an investigation. The 5xx baseline was already noisy, so the start of the Fastly problem was easy to miss, and part of that noise turned out to be one of the bugs.
Sources
Related cases
IL-0343DNS names under digitaloceanspaces.com stopped resolving, breaking Spaces, Container Registry and the Control PanelDigitalOcean · 2024same root cause · shared Object storage
IL-0257canva.com went down for about 50 minutes when 1.5 million requests per second OOM-killed every API Gateway taskCanva · 2024same root cause · shared CDN and edge network
IL-0267Wikimedia's eqsin cache site went unreachable when both of its transport links to the core data centers were downWikimedia Foundation · 2023same root cause · shared CDN and edge network
IL-0126The OPT-175B training run restarted more than 40 times in two weeks as cloud GPU nodes failed with ECC errors, replacement nodes came back faulty, and checkpoint downloads hungMeta AI · 2021same root cause · shared Object storage
IL-0398GOV.UK showed "Error 503 Service Unavailable" pages for under an hour during a global outage of its primary CDNGovernment Digital Service · 2021same root cause · shared CDN and edge network
Check your cluster for this
For AI tools and scripts
- This case as JSON: https://incidentlib-api.benchlet.com/cases/IL-0515
- The cases most like it: https://incidentlib-api.benchlet.com/cases/IL-0515/similar
- MCP server (Streamable HTTP, no key):
https://incidentlib-mcp.benchlet.com/mcp
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.