BerriAI/litellm · error · HTTPException
User does not have permission to update this user. Only PROX
Error message
User does not have permission to update this user. Only PROXY_ADMIN can update other users.
What it means
On /user/update, when the target user row exists, can_user_call_user_update allows the call only if the caller is proxy_admin or the target is the caller's own user_id; anything else returns 403. Note the detail is a JSON object {'error': ...} rather than a plain string. Team admins are NOT exempt on this user-management endpoint - only self-updates and proxy admins pass.
Source
Thrown at litellm/proxy/management_endpoints/internal_user_endpoints.py:1266
)
)
except Exception as audit_error:
verbose_proxy_logger.warning("Failed to create audit log for user %s: %s", response.get("user_id"), audit_error)
def _check_user_update_authz(
user_request: UpdateUserRequest,
user_api_key_dict: UserAPIKeyAuth,
existing_user_row: BaseModel | None,
) -> None:
"""Authorization checks for /user/update — raises HTTPException on failure."""
if user_request.user_role is not None and user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN.value:
raise HTTPException(status_code=403, detail="Only proxy admins can modify user roles.")
if existing_user_row is not None:
typed_row: Final = LiteLLM_UserTable.model_validate(existing_user_row.model_dump(exclude_none=True))
if not can_user_call_user_update(user_api_key_dict=user_api_key_dict, user_info=typed_row):
raise HTTPException(
status_code=403,
detail={
"error": "User does not have permission to update this user. Only PROXY_ADMIN can update other users."
},
)
elif user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN.value:
# Silent-create guard: only PROXY_ADMIN may create via /user/update.
raise HTTPException(
status_code=404,
detail={
"error": "User not found. Only PROXY_ADMIN can create users via /user/update; use /user/new instead."
},
)
async def _invalidate_user_spend_counter_if_changed(
non_default_values: Mapping[str, object],
) -> None:View on GitHub (pinned to 77b7c6c40c)
Solutions
- Authenticate with a proxy_admin key to update other users
- Non-admins: only send updates for their own user_id (or omit user_id to target self)
- For team-scoped management, use the team member management endpoints or have an admin perform user updates
Example fix
# before: member key updating a teammate
POST /user/update -H 'Authorization: Bearer sk-member1' {"user_id": "member2", "max_budget": 10} # 403
# after: admin key
POST /user/update -H 'Authorization: Bearer sk-admin' {"user_id": "member2", "max_budget": 10} # 200 Defensive patterns
Strategy: validation
Validate before calling
import requests
def can_update_target(base_url: str, key: str, target_user_id: str) -> bool:
r = requests.get(f"{base_url}/key/info", params={"key": key}, timeout=10)
r.raise_for_status()
info = r.json()["info"]
return info.get("user_role") == "proxy_admin" or info.get("user_id") == target_user_id Type guard
def updateWillPassAuthz(keyRole: string, keyUserId: string, targetUserId: string): boolean {
return keyRole === "proxy_admin" || keyUserId === targetUserId;
} Try / catch
except requests.HTTPError as e:
body = e.response.text if e.response is not None else ""
if e.response is not None and e.response.status_code == 403 and "does not have permission" in body:
# target is another user: re-issue with admin key or skip
... Prevention
- Per-user operations should use that user's own key; batch edits should use an admin key
- Do not assume team-admin rights extend to /user/update - they do not
- Cache the caller's identity from /key/info and route updates accordingly
When it happens
Trigger: POST /user/update with the user_id or user_email of another user while authenticated as internal_user or team_admin; scripts that enumerate and update many users with a single member key.
Common situations: Team admins assuming they can edit team members through /user/update; frontends reusing one member's key for everyone's profile saves; shared service keys used for HR-style bulk edits.
Related errors
- f"Only proxy admins can create administrative users (proxy_a
- Only proxy admins can modify user roles.
- User {user_api_key_dict.user_id} does not have access to vec
- Only admins or team admins can create projects. Your role is
- Only admins or team admins can update projects
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/2326cfc10a720c6f.
Report an issue: GitHub.