{"record":{"id":"0247dead68599d38","repo":"BerriAI/litellm","slug":"max-budget-requested-max-budget-cannot-exceed","errorCode":null,"errorMessage":"max_budget ({_requested_max_budget}) cannot exceed the caller's own max_budget ({delegation_ceiling}).","messagePattern":"max_budget \\((.+?)\\) cannot exceed the caller's own max_budget \\((.+?)\\)\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/management_endpoints/key_management_endpoints.py","lineNumber":957,"sourceCode":"                \"error\": (\n                    f\"max_budget ({_requested_max_budget}) cannot be set without \"\n                    \"specifying team_id when using a CLI session token.\"\n                )\n            },\n        )\n    delegation_ceiling: Final = (\n        user_api_key_dict.max_budget\n        if user_api_key_dict.max_budget is not None\n        else (team_table.max_budget if user_api_key_dict.is_session_token and team_table is not None else None)\n    )\n    if (\n        user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN.value\n        and not is_ui_session_team_key\n        and _requested_max_budget is not None\n        and delegation_ceiling is not None\n        and _requested_max_budget > delegation_ceiling\n    ):\n        raise HTTPException(\n            status_code=400,\n            detail={\n                \"error\": (\n                    f\"max_budget ({_requested_max_budget}) cannot exceed the caller's \"\n                    f\"own max_budget ({delegation_ceiling}).\"\n                )\n            },\n        )\n\n    _check_budget_limits_delegation_ceiling(\n        budget_limits=data.budget_limits,\n        delegation_ceiling=delegation_ceiling,\n        user_api_key_dict=user_api_key_dict,\n        is_ui_session_team_key=is_ui_session_team_key,\n        team_table=team_table,\n    )\n    _check_permissions_caller_permission(\n        data=data,","sourceCodeStart":939,"sourceCodeEnd":975,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/key_management_endpoints.py#L939-L975","documentation":"LiteLLM Proxy enforces a delegation ceiling: a non-admin caller (or a session token not targeting its own UI team) cannot give a new key a max_budget larger than the caller's own effective max_budget — their key's max_budget, or for session tokens the owning team's max_budget. This stops users from escalating spend authority they were never granted.","triggerScenarios":"POST /key/generate or /key/update where the caller is not a proxy admin, the body's \"max_budget\" is a number, delegation_ceiling is not None, and _requested_max_budget > delegation_ceiling (e.g. a key capped at $50 tries to mint a $100 key).","commonSituations":"Self-service tooling lets users pick arbitrary budgets; an admin lowered a user's/key's budget after the script was written; a session token whose team budget is smaller than the requested key budget.","solutions":["Set the new key's max_budget to a value <= the caller's own max_budget (or the team's, for session tokens)","Ask a proxy admin to first raise the caller's key budget (or team max_budget), then retry","If the caller should genuinely have this authority, have a proxy admin create the key directly"],"exampleFix":"# before: caller's own key has max_budget=50\nrequests.post(f\"{PROXY}/key/generate\", headers=AUTH, json={\"max_budget\": 100})\n\n# after\nrequests.post(f\"{PROXY}/key/generate\", headers=AUTH, json={\"max_budget\": 50})","handlingStrategy":"validation","validationCode":"# Fetch the caller's own key info and clamp the delegated budget\nme = requests.get(f\"{PROXY}/key/info\", headers=AUTH, params={\"key\": CALLER_KEY}).json()\nceiling = me[\"key_info\"][\"max_budget\"]\nif ceiling is not None:\n    payload[\"max_budget\"] = min(payload[\"max_budget\"], ceiling)","typeGuard":null,"tryCatchPattern":"try:\n    resp = requests.post(f\"{PROXY}/key/generate\", headers=AUTH, json=payload)\nexcept requests.HTTPError as e:\n    if e.response.status_code == 400 and \"cannot exceed the caller's own max_budget\" in e.response.text:\n        payload[\"max_budget\"] = ceiling  # retry at the ceiling value\n        resp = requests.post(f\"{PROXY}/key/generate\", headers=AUTH, json=payload)\n    else:\n        raise","preventionTips":["Read the delegating key's max_budget before minting child keys and clamp","Route budget increases through an admin workflow instead of retrying bigger numbers","For session tokens, treat the owning team's max_budget as the ceiling"],"tags":["litellm-proxy","budget","authorization","virtual-keys","privilege-escalation"],"backgroundTag":"budget-limit-exceeded","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}