快速结论:该报错通常出现在 LiteLLM Proxy 启用 JWT 认证并配置了 virtual_key_claim_field 的场景下,当同一用户从多个应用(如不同 OIDC 客户端)登录时,第二个应用不会重新解析 team_id_jwt_field。优先排查 virtual_key_claim_field 的取值是否被两个应用共享(例如都用 preferred_username)。
适用环境:LiteLLM v1.103.1;Helm chart 部署,组件化模式;启用 enable_jwt_auth: true 与 litellm_jwtauth 配置。
最快修复方案:将 virtual_key_claim_field 指向每个应用各不相同的 claim(例如 OIDC 客户端 id 或 azp),或为每个应用配置独立的 issuer 条目;这样两个应用会解析到不同的 virtual key。
注意事项:该方案下 mapping 是按应用(per app)共享,而不是按用户+应用(per user and app)区分,同一应用内所有用户会共用同一映射。Issue 中维护者只验证了 mapping lookup 逻辑,未端到端测试 auto_register。按用户+应用独立建 key,或在映射时额外校验 team claim 与 key 所属 team,属于尚未设计的新功能,非当前已有能力。
问题场景
用户使用 LiteLLM Proxy,通过 JWT → virtual key 映射来按应用限制模型访问权限。配置了多个 team,不同 team 可访问不同模型;JWT issuer 根据请求来源(app 1 / app 2)在 JWT 中写入不同的 user-role claim,并配置 team_id_jwt_field: user-role。用户首次从 app 1 连接时能被正确映射到对应 team,但从 app 2 连接时 team 映射被忽略,仍继续复用 app 1 首次创建的 virtual key,导致 app 2 的 team claim 从未生效。
报错原文
[Bug]: Team ID not verified on JWT
原因分析
维护者复查当前 main 分支后判断,问题来自 key mapping 的匹配方式,而不是 team claim 本身失效:
- 当
virtual_key_claim_field: preferred_username时,查找是以 issuer、该字段名及其值为 key 进行的。 - 两个应用发送的用户名相同,因此第二次登录会命中第一次登录创建的 key 并复用它。
- 一旦 mapping 匹配成功,正常的 JWT 路径会被跳过,而
team_id_jwt_field只在正常 JWT 路径中被读取,所以来自 app 2 的 team claim 从未被读取。
维护者在仅 mock 数据库边界、使用真实 mapping 查找的情况下复现:两个 JWT 具有相同的 preferred_username、不同的 user-role,会解析到同一个 key 和 team;若把 virtual_key_claim_field 改为 user-role,则解析为两个不同的 key 和 team。
环境排查
- 确认 LiteLLM 版本(Issue 中为 v1.103.1)。
- 确认部署方式(Issue 中为 Helm chart,componentized)。
- 检查
litellm_jwtauth下virtual_key_claim_field的取值,是否为所有应用共享(如preferred_username)。 - 检查
team_id_jwt_field/team_ids_jwt_field指向的 claim,以及各应用 JWT 中该 claim 的值。 - 检查
unregistered_jwt_client_behavior(Issue 中为auto_register)与user_id_upsert配置。 - 在 LiteLLM 管理界面确认该用户对应的 key 所属 team 是否为 app 1(验证 key 是否被复用)。
解决步骤
- 确认现象:用户从 app 1 首次登录后,在 admin UI 检查该用户对应的 key 是否只显示 team app1。维护者建议先做这一项自查,以确认 key 复用的判断成立。
- 将
virtual_key_claim_field从preferred_username改为每个应用各不相同的 claim,例如 OIDC 客户端 id 或azp(前提是两个应用是不同的客户端)。这样两个应用会解析到不同的 key 和 team。 - 或者为每个应用配置独立的 issuer 条目,使不同应用走不同的 JWT 路径。
- 如果已经使用
team_ids_jwt_field(claim 值包含多个 team,如["app1","app2"])并通过x-litellm-team-id选择 team,需要注意:auto_register首次请求只按当次解析出的单个 team 创建 mapping 与 virtual key。发送x-litellm-team-id: app1时 key 只带 app1,team_ids_jwt_field允许 header 从 claim 中挑选 team,但不会在创建时把用户加入 claim 中的每一个 team。 - 若需要按用户+应用独立建 key,或在映射时校验 team claim 与 key 所属 team,这属于新功能,需要向维护者提交 feature request(Issue 中用户表示会自行提交)。
验证方法
在修改 virtual_key_claim_field(或 issuer 配置)后,分别用 app 1 与 app 2 的 JWT 登录,观察是否解析到两个不同的 virtual key,并检查各自对应的 team 是否为 app 1 与 app 2。若两个应用仍命中同一 key,则说明用于区分的 claim 取值仍相同。Issue 中维护者仅验证了 mapping lookup 逻辑,未端到端跑通 auto_register,因此涉及自动注册的完整链路需要自行确认。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


