快速结论:当 LiteLLM Proxy 使用默认 aiohttp 传输层调用 /v1/responses 端点时,DNS 解析期间偶发的 asyncio.CancelledError 不会被任何错误处理层捕获,导致直接返回裸 500、没有重试也没有日志。优先排查 aiohttp 传输层的异常映射代码是否已包含对 asyncio.CancelledError 的处理。
适用环境:LiteLLM v1.81.9-stable,Azure OpenAI Provider,/v1/responses 端点,默认 aiohttp 传输(未设置 disable_aiohttp_transport),多区域 Deployment 使用 simple-shuffle 路由。
最快修复方案:暂无确认的一步修复方案。Issue 中提出的修复 PR 已更新为在两个位置处理 asyncio.CancelledError:在 aiohttp_transport.py 中增加独立的 except asyncio.CancelledError 分支并映射到 httpx.ConnectError,同时在 AIOHTTP_EXC_MAP 中补充 asyncio.CancelledError: httpx.ConnectError 映射,但该 PR 尚未合并,需等待官方发布包含此修复的版本。
注意事项:由于 Issue 已被标记为 stale 且 PR 仍在审查中,此修复尚未在稳定版中验证。单纯将 asyncio.CancelledError 加入 except (Exception, asyncio.CancelledError) 不会生效,因为该异常在 AIOHTTP_EXC_MAP 中没有对应条目,会被捕获后原样重新抛出。
问题场景
用户通过 LiteLLM Proxy 调用 Azure OpenAI 的 /v1/responses 端点(使用 OpenAI SDK 的 responses.parse() 方法),为同一模型配置了多个区域 Deployment 并启用 simple-shuffle 负载均衡。在持续数小时到数天的高负载下,偶发请求在 aiohttp connector 的 DNS 解析阶段抛出 asyncio.CancelledError,客户端收到不带任何错误详情的裸 500。
报错原文
[Bug]: asyncio.CancelledError in aiohttp transport bypasses retry logic, logging, and exception mapping
asyncio.exceptions.CancelledError
Traceback (most recent call last):
File "ddtrace/contrib/internal/httpx/patch.py", line 137, in _wrapped_async_send
resp = await wrapped(*args, **kwargs)
...
File "litellm/llms/custom_httpx/aiohttp_transport.py", line 240, in _make_aiohttp_request
response = await client_session.request(...)
File "aiohttp/client.py", line 1510, in __aenter__
self._resp = await self._coro
File "aiohttp/connector.py", line 1178, in _resolve_host
return await asyncio.shield(resolved_host_task)
asyncio.exceptions.CancelledError
原因分析
根本原因已由维护者在代码审查中确认:asyncio.CancelledError 在 Python 3.9+ 中继承自 BaseException 而非 Exception,导致三层错误处理全部漏接:
aiohttp_transport.py中的map_aiohttp_exceptions()只捕获Exception,CancelledError直接穿透;router.py的_acompletion只捕获Exception进行重试和日志记录,CancelledError不会被记录或重试;proxy_server.py的openai_exception_handler只捕获ProxyException。
结果:路由器不会在其它健康 Deployment 上重试,代理日志和 LiteLLM UI 均无任何记录,num_retries 和 fallback 配置完全失效。该问题为间歇性,依赖 DNS 缓存时序和并发请求模式,难以按需复现。
环境排查
- 确认 LiteLLM Proxy 版本是否为 v1.81.9-stable 或更早版本(修复 PR 尚未合并到稳定版)。
- 确认是否使用默认 aiohttp 传输层(即未设置
disable_aiohttp_transport环境变量)。 - 确认路由配置是否为 simple-shuffle 且每个模型配置了多个 Azure OpenAI 区域 Deployment。
- 确认 Python 版本是否为 3.9+(
asyncio.CancelledError在 3.9 起继承BaseException)。 - 检查是否正确配置了
num_retries和 fallback 参数,并确认这些参数在出问题时完全未生效。
解决步骤
- 查看本地安装的
aiohttp_transport.py源码,确认map_aiohttp_exceptions()中是否只包含except Exception,并且AIOHTTP_EXC_MAP中是否缺少asyncio.CancelledError条目。 - 若需临时缓解,可尝试设置
disable_aiohttp_transport=true切换回 httpx 传输层,观察问题是否消失(Issue 作者未验证此方案,仅为可能缓解手段)。 - 关注修复 PR 的合并状态:修复方案是在
map_aiohttp_exceptions()中except Exception之前增加独立的except asyncio.CancelledError分支,直接映射为httpx.ConnectError,同时在AIOHTTP_EXC_MAP中补充asyncio.CancelledError: httpx.ConnectError。 - 在官方发布包含该修复的版本后,升级 LiteLLM 到对应版本。请勿仅将异常加入
except (Exception, asyncio.CancelledError),这会因映射表缺失而变成空操作。
验证方法
修复是否生效可以从两个层面确认:代码层面,检查上述两个位置的改动是否已出现在安装版本中;运行层面,在持续负载下观察是否仍有请求返回裸 500,且 Proxy 日志和 LiteLLM UI 中是否能看到该异常被记录、路由器是否在备用 Deployment 上执行了重试。由于问题为间歇性且难以按需复现,建议修复后在类似负载条件下观察一段时间再下结论。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Question]: why my RAPTOR always use the wrong embedding model?](https://www.chat-gpts.plus/wp-content/uploads/2026/09/7679-06f85f40-768x403.jpg)

