快速结论:在 LiteLLM Proxy 上通过 x-litellm-timeout(或请求体里的 timeout)传入超时后,Router 重试与 Retry-After 等待仍按单次尝试计时,不会检查调用方剩余总预算,容易在客户端已超时放弃后继续重试、放大上游负载。排查时应优先确认调用方超时值、num_retries 以及上游返回的 Retry-After。
适用环境:Issue 报告在 LiteLLM 1.106.0 观察到该问题,并指出当时 main 分支的 litellm/router.py 仍是同样的重试循环;未提供操作系统、Python、CUDA、显卡等环境信息。
最快修复方案:暂无确认的一步修复方案。Issue 中描述的修复方式是把调用方超时当作整次 Router 调用的绝对 deadline,并提交了 PR #50013,但评论未确认该 PR 已合并或已发布。
注意事项:修复思路属于基于 Issue 讨论的方案描述,不是已验证的现成版本;升级前应确认所用版本是否包含对应改动。讨论中还提到 fallbacks 无法按状态码限制,这是另一项相关功能请求,不应与本超时问题混为一谈。
问题场景
用户在 LiteLLM Proxy 上调用模型,请求携带 x-litellm-timeout(或请求体中的 timeout),同时配置了重试次数 num_retries。当上游部署快速返回 503 并带 Retry-After 头时,Router.async_function_with_retries 会按 _time_to_sleep_before_retry 等待后继续重试,而不检查调用方剩余的总时间预算。Issue 给出的复现场景是:Retry-After: 6、num_retries: 3、客户端发送 x-litellm-timeout: 10,Proxy 最终花费约 20 秒重试,此时客户端早已超时并发起自己的重试,恰好在供应商承压时让上游请求量翻倍。
报错原文
[Bug]: Router retries and Retry-After sleeps ignore the caller's request timeout (x-litellm-timeout / x-stainless-timeout)
原因分析
按 Issue 讨论的结论,根因是 Proxy 把调用方超时当作单次尝试的上限,而不是整个请求的总截止时间。因此每次重试前的退避等待和每次尝试本身都不会被剩余预算约束。此外,OpenAI SDK 会在每个请求上发送 x-stainless-timeout(单位:秒),但 Proxy 完全没有读取该头,导致默认 OpenAI SDK 客户端实际上没有获得任何截止时间限制。
环境排查
- 确认 LiteLLM 版本;Issue 在 1.106.0 上观察到该行为。
- 确认代理请求是否携带
x-litellm-timeout或请求体timeout,以及具体数值。 - 确认是否使用 OpenAI SDK 客户端;若是,检查请求是否携带
x-stainless-timeout。 - 确认 Router 配置中的
num_retries和模型列表中的fallbacks配置。 - 确认上游返回的状态码与
Retry-After响应头数值,判断重试等待是否可能超出调用方超时。
解决步骤
- 先复现并记录一次请求的总耗时、上游
503次数、每次Retry-After数值以及num_retries,确认总耗时明显超过调用方设置的超时。 - 检查 Proxy 是否读取
x-stainless-timeout;在修复前,代理不会把该头作为x-litellm-timeout缺失时的回退超时。 - 可优先尝试的缓解方式:下调
num_retries,或让调用方显式发送x-litellm-timeout;这只能减少重试放大,Issue 未验证其能实现总截止时间语义。 - 关注 PR #50013 的合并与发布状态,升级到包含该修复的 LiteLLM 版本后再做端到端截止时间验证。
验证方法
用与原复现相同的条件(上游快速返回 503 且带 Retry-After: 6,客户端设置 x-litellm-timeout: 10)发起请求,确认代理在截止时间前返回最后一次错误或 408/504,不再启动无法在截止时间前完成的等待或重试,且单次尝试的超时被剩余预算限制。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: Xiaomi MiMo models: 'output_config' parameter causes AsyncCompletions.create() to fail with Claude Code](https://www.chat-gpts.plus/wp-content/uploads/2026/11/24549-4769d317-768x403.jpg)
![[Bug]: rust vllm-bench result is quite different from vllm bench serve](https://www.chat-gpts.plus/wp-content/uploads/2026/11/59154-ea9f2c53-768x403.jpg)
![[Bug]: [ROCm] Qwen4Exp (AMD path): PLE n-gram IDs read a stale query_start_loc tail during PIECEWISE CUDA-graph replay](https://www.chat-gpts.plus/wp-content/uploads/2026/11/61486-25e2f379-768x403.jpg)