BerriAI/litellm · error · HTTPException
Admin-only endpoint. Your user role=
Error message
Admin-only endpoint. Your user role={user_api_key_dict.user_role} What it means
GET /customer/list is restricted to PROXY_ADMIN and PROXY_ADMIN_VIEW_ONLY roles taken from the authenticated key's user (user_api_key_dict.user_role). Any other role (internal_user, team member, etc.) gets HTTP 401 with the caller's actual role echoed in the message. Note the DB check on this route comes after the role check.
Solutions
- Call with the master key (LITELLM_MASTER_KEY) or a key whose user has the proxy_admin role
- An admin can elevate the user via /user/update (role: proxy_admin), or issue a proxy_admin_view_only key for read-only access
- Non-admin callers should use scoped endpoints (e.g. GET /customer/info) instead of the full listing
Example fix
# before
headers = {"Authorization": "Bearer sk-team-key"} # internal_user role -> 401
# after
headers = {"Authorization": "Bearer sk-master-key"} # proxy_admin -> 200 Defensive patterns
Strategy: validation
Validate before calling
import httpx
def is_admin_key(base: str, headers: dict) -> bool:
key = headers["Authorization"].split(" ", 1)[1]
info = httpx.get(f"{base}/key/info", params={"key": key}, headers=headers).json()
role = (info.get("key_info") or {}).get("user_role")
return role in ("proxy_admin", "proxy_admin_view_only") Try / catch
try:
r = httpx.get(f"{base}/customer/list", headers=headers)
except httpx.HTTPStatusError as e:
if e.response.status_code == 401 and "Admin-only endpoint" in e.response.text:
raise PermissionError("/customer/list needs a proxy_admin key") from e
raise Prevention
- Store admin and non-admin keys separately in secret managers and label them clearly
- Check the key's user_role via /key/info before scripting admin endpoints
- Grant proxy_admin_view_only for reporting tooling that only needs to read
When it happens
Trigger: Calling GET /customer/list with a virtual key whose owning user is not a proxy admin - team-scoped keys, personal keys, or org-member keys created via /user/new.
Common situations: Operators holding team keys try to enumerate all customers; scripts pull the wrong secret from a vault; new staff have the default internal_user role and attempt admin operations on day one.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- Access denied to MCP server
- Admin-only endpoint. Not allowed to access this., your role=
- Call not allowed to delete MCP server. User is not a proxy…
- Customer already exists, passed user_id=
- DB not connected. This endpoint needs a database; set…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/2c6877f009f545be.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/proxy/management_endpoints/customer_endpoints.py:844
) -> list[CustomerResponse]:
"""
[Admin-only] List all available customers
Example curl:
```
curl --location --request GET 'http://0.0.0.0:4000/customer/list' \
--header 'Authorization: Bearer sk-1234'
```
"""
try:
from litellm.proxy.proxy_server import prisma_client
if (
user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN
and user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY
):
raise HTTPException(
status_code=401,
detail={"error": f"Admin-only endpoint. Your user role={user_api_key_dict.user_role}"},
)
if prisma_client is None:
raise HTTPException(
status_code=400,
detail={"error": CommonProxyErrors.db_not_connected_error.value},
)
response: Final = await _typed_table(EndUserRepository(prisma_client)).find_many(
include={"litellm_budget_table": True, "object_permission": True}
)
return [_to_customer_response(item) for item in response]
except Exception as e:
verbose_proxy_logger.exception(View on GitHub (pinned to 77b7c6c40c)