BerriAI/litellm · error · HTTPException

User={change_initiated_by.user_id} is not a Proxy Admin or T

Error message

User={change_initiated_by.user_id} is not a Proxy Admin or Team Admin for team={team.team_id}. Please ask your Proxy Admin to allow this action under 'Member Permissions' for this team.

What it means

LiteLLM only lets a team-scoped key change be initiated by a Proxy Admin, a Team Admin of that team, or a member who was explicitly granted the KEY_UPDATE permission under the team's Member Permissions. The change_initiated_by identity (derived from the calling virtual key / user) failed all three checks, so the 403 explains both who was rejected and the remediation path (Member Permissions).

Source

Thrown at litellm/proxy/management_endpoints/key_management_endpoints.py:3346

                detail=f"User={key.user_id} is not a member of the team={team.team_id}. Check team members via `/team/info`.",
            )

    # Check if the person initiating the change is a Proxy Admin or Team Admin
    if (
        change_initiated_by.user_role == LitellmUserRoles.PROXY_ADMIN.value
        or _is_user_team_admin(
            user_api_key_dict=change_initiated_by,
            team_obj=team,
        )
        or TeamMemberPermissionChecks.does_team_member_have_permissions_for_endpoint(
            team_member_object=member_object,
            team_table=cast(LiteLLM_TeamTableCachedObj, team),
            route=KeyManagementRoutes.KEY_UPDATE.value,
        )
    ):
        return
    else:
        raise HTTPException(
            status_code=403,
            detail=f"User={change_initiated_by.user_id} is not a Proxy Admin or Team Admin for team={team.team_id}. Please ask your Proxy Admin to allow this action under 'Member Permissions' for this team.",
        )


@router.post("/key/delete", tags=["key management"], dependencies=[Depends(user_api_key_auth)])
@management_endpoint_wrapper
async def delete_key_fn(
    data: KeyRequest,
    user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
    litellm_changed_by: str | None = Header(
        None,
        description="The litellm-changed-by header enables tracking of actions performed by authorized users on behalf of other users, providing an audit trail for accountability",
    ),
):
    """
    Delete a key from the key management system.

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Have a Proxy Admin (master key) perform the key update instead.
  2. Or add the caller as team_admin: POST /team/member_add with role team_admin (or /team/update changing the member's role).
  3. Or grant the KEY_UPDATE member permission for the team: PATCH /team/{team_id}/member/permissions (Enterprise UI: Team Settings -> Member Permissions).

Example fix

# before (internal-user key)
client.headers["Authorization"] = "Bearer sk-user-key"
client.post("/key/update", json={"key": "sk-target", "metadata": {...}})

# after (proxy admin master key)
client.headers["Authorization"] = "Bearer sk-master"
client.post("/key/update", json={"key": "sk-target", "metadata": {...}})
Defensive patterns

Strategy: try-catch

Try / catch

try:
    client.post("/key/update", json={"key": target_key, ...})
except HTTPError as e:
    if e.response.status_code == 403 and "not a Proxy Admin or Team Admin" in e.response.text:
        escalate_to_proxy_admin(target_key)  # or use master-key credential
    else:
        raise

Prevention

When it happens

Trigger: A plain internal-user key calling POST /key/update (or /team/key/bulk_update) on a key belonging to a team where the caller is only a 'user' role member; a new admin using a personal key before being made team_admin.

Common situations: Delegating key rotation to a team member without granting member permissions; a service account key (not bound to an admin user) attempting team key updates; admin left the org and their replacement's key lacks roles.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/0bcfda37211a292e. Report an issue: GitHub.