内容提要
2026年8月,PyPI文件托管服务因Fastly缓存节点配置错误及自身配置缺陷,出现间歇性502/503错误。问题源于Fastly金丝雀部署回滚不匹配,以及B2回退、分段缓存等自身bug。修复后错误率大幅下降,团队建议用户启用依赖缓存以减少请求。
延伸解读
故障根因:外部与内部配置问题叠加
本次事件并非单一原因造成。Fastly 金丝雀部署回滚不匹配导致一个缓存节点持续返回 502,同时 PyPI 自身配置存在多个隐藏 bug:B2 无响应时未触发 S3 回退、分段缓存对后缀范围请求返回 501、URL 规范化顺序错误导致错误响应被缓存。这些内部问题早已存在,但直到外部故障引发调查才被发现。
影响范围与恢复时间线
故障从 8 月 15 日开始,持续约两周,期间用户间歇性遇到 502/503 错误,影响安装流程。8 月 18 日有用户记录到 6 小时内 88 次 502,涉及 32 个包。团队通过用户报告定位到单一缓存节点,并逐步修复内部配置。8 月 28 日 Fastly 修复金丝雀问题后,下载完全恢复。
对用户的建议:启用依赖缓存
报告指出,大量流量来自 CI 作业重复下载相同依赖,尤其是 GitHub Actions。建议用户启用依赖缓存(如 setup-python 的 cache 选项),这样未变化的依赖不会再次请求文件托管服务,减少请求量,也能降低因服务故障导致构建失败的风险。
Q&A
2026年8月PyPI文件托管服务出现502/503错误的原因是什么?
原因有两个:一是Fastly金丝雀部署回滚不匹配,导致一个缓存节点配置错误,返回502;二是PyPI自身的Fastly配置存在多个bug,包括B2回退逻辑缺陷、分段缓存对特定范围请求处理不当等。
PyPI文件托管服务是如何工作的?
files.pythonhosted.org是Fastly CDN服务,后端有三个源:B2、S3和Conveyor。文件上传时先存S3,再同步到B2。读取时Fastly先尝试B2,若B2失败则回退到S3。Conveyor处理非包文件请求。缓存文件不可变,Cache-Control设为max-age=365000000。
PyPI文件托管错误对用户有什么影响?
用户在安装包时可能遇到间歇性502和503错误,导致安装失败。错误影响范围包括PEP 658元数据的小范围请求,以及大文件下载。
PyPI团队修复了哪些自身配置bug?
修复了三个bug:1) B2无响应时未触发S3回退;2) 分段缓存不支持后缀范围请求,返回501;3) URL规范化顺序错误导致缓存了错误的501响应。
Fastly金丝雀部署问题是如何解决的?
Fastly移除了影响PyPI流量的路由覆盖,并最终修补了底层金丝雀配置bug,同时将PSF流量从金丝雀队列中排除。
PyPI团队建议用户如何减少对文件托管服务的依赖?
建议用户启用依赖缓存,例如在GitHub Actions中使用setup-python的缓存功能(需显式开启)或setup-uv的缓存(默认开启),以减少重复下载请求。
事件期间错误率的变化趋势是怎样的?
从8月15日起错误率上升,8月21日达到峰值(接近百万次5xx),修复后错误率大幅下降,比事件前基线低两到三个数量级。
PyPI团队如何发现并定位问题?
通过用户提交的支持工单,特别是#11925将问题定位到单个Fastly缓存节点,结合Datadog日志和x-served-by头确认。