快速结论:在 LiteLLM Proxy 中使用交互式 OAuth2 MCP 服务器(指定了 authorization_url、token_url 和 registration_url 但 issuer 留空)时,系统会自动将发现的 issuer 持久化到数据库,导致服务器进入“issuer-anchored”模式。此后若一次 issuer 元数据获取失败,/authorize 将永久返回 400 错误,直到有管理员触发数据库写入操作。优先排查是否是自动填充的 issuer 导致了锚定。
适用环境:LiteLLM Proxy(具体版本未在 Issue 中明确,但涉及 litellm/proxy/_experimental/mcp_server/ 模块)。
最快修复方案:该问题已在 PR #34990 中修复,但尚未提及是否已合入正式版本。暂无一步到位的手动修复方案;可尝试删除并重新创建受影响的服务器,但若再次触发自动发现仍可能复现。
注意事项:修复方案需要等待包含该修复的 LiteLLM 版本发布并升级;在此之前,若必须使用 OAuth2 交互式服务器,可以考虑手动指定 issuer 并确保元数据获取稳定,或临时禁用 issuer 发现功能(需自行评估风险)。
问题场景
用户在 LiteLLM Proxy 中通过 API 创建一个交互式 OAuth2 MCP 服务器,请求体提供了 authorization_url、token_url 和 registration_url,但 issuer 字段留空。服务器初始工作正常,但大约一分钟后再次调用 GET /v1/mcp/server/oauth/{server_id}/authorize 时返回 400 错误,且持久错误直到管理员执行某些配置写入操作才会恢复。
报错原文
400 {"detail":"MCP server authorization url is not configured..."}
(Issue 标题原文:[Bug]: MCP OAuth: persisted discovered issuer flips servers into issuer-anchored mode; one failed metadata fetch then breaks /authorize until a config write)
原因分析
根本原因是四个行为交互导致的逻辑缺陷:
- 自动持久化发现 issuer:
MCPServerManager._persist_discovered_oauth_endpoints在注册表构建后运行,将发现的 issuer 写入数据库行中issuer列为空的行。 - 误将发现 issuer 视为管理员固定: 下一次构建时
_uses_issuer_anchor将任何存在issuer的行视为管理员锚定,但并未保存该 issuer 是发现来源还是管理员明确设置的(issuer_is_anchored仅存在于内存中),导致服务器无声切换至锚定模式。 - 锚定模式丢弃存储的端点: 在锚定模式下
_endpoints_yield_to_issuer会忽略数据库里存储的authorization_url等列,强制每次构建都通过 RFC 8414 元数据获取来确定端点。 - 一次失败导致永久故障: 当该元数据获取失败(网络抖动、限流等),由于锚定模式下
_carry_forward_resolved_oauth_endpoints会跳过锚定服务器,导致authorization_url为None,且reload_servers_from_database的快速路径因updated_at未变化而不会重试,从而造成永久性故障。
此外,诊断困难点在于:列表端点 GET /v1/mcp/server 返回解析后的视图(显示 null),而单个服务器端点 GET /v1/mcp/server/{server_id} 仍显示数据库中的原值,容易误导管理员以为是字段被清空。
环境排查
- 确认 LiteLLM Proxy 版本(若已知,请升级包含 PR #34990 修复的版本)。
- 检查
GET /v1/mcp/server/{server_id}返回的issuer字段是否被自动填充,以及updated_at是否在未管理员操作时发生变化。 - 查看数据库记录中
issuer字段的值是否与用户指定的端点来源一致。
解决步骤
- 临时恢复服务: 在未修复的版本中,可通过执行一次触发
updated_at变更的操作(如重新创建服务器)强制触发重建,但可能再次重复此问题。也可手动删除该服务器并重新创建,但需注意同样会在下一次注册表构建时重新触发缺陷。 - 升级 LiteLLM: 安装包含 PR #34990 修复的版本(例如等待新发布)。该修复包含两部分:
- 将发现的 issuer 保存在独立的
credentials.discovered_issuer字段中,并通过_admin_pinned_issuer区分管理员固定与发现来源,使发现 issuer 不再转入锚定模式。 - 对于缺少必要端点的服务器,将免除快速路径缓存,从而在下一次正常重载时触发发现重试,自动恢复。
- 将发现的 issuer 保存在独立的
- 验证修复: 升级后重新创建受影响的服务器
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Bug]: CJK characters from concurrent requests bleed into unrelated streams (cross-request contamination in streaming)](https://www.chat-gpts.plus/wp-content/uploads/2026/07/35023-0b86a9d1-768x403.jpg)
