BerriAI/litellm · error · ValueError

Only premium users can add tags to keys. {CommonProxyErrors.

Error message

Only premium users can add tags to keys. {CommonProxyErrors.not_premium_user.value}

What it means

Key tagging is an enterprise feature: while building the key record, LiteLLM raises a plain ValueError (not an HTTPException) if "tags" is present in the payload and the server is not premium (LITELLM_LICENSE unset/invalid). Because it is a ValueError it escapes the normal error mapping and usually surfaces as an HTTP 500 rather than a clean 400.

Source

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

        data_json["budget_id"] = _budget_id

    # Only set budget_duration on key when explicitly provided. Keys with budget_id
    # but no explicit budget_duration follow their linked budget tier's schedule;
    # reset_budget_for_litellm_budget_table() resets them when the tier resets.
    # This avoids duplicating budget_duration on keys so tier updates apply automatically.
    if "budget_duration" in data_json:
        data_json["key_budget_duration"] = data_json.pop("budget_duration", None)

    if user_api_key_dict.user_id is not None:
        data_json["created_by"] = user_api_key_dict.user_id
        data_json["updated_by"] = user_api_key_dict.user_id

    # Set tags on the new key
    if "tags" in data_json:
        from litellm.proxy.proxy_server import premium_user

        if premium_user is not True and data_json["tags"] is not None:
            raise ValueError(f"Only premium users can add tags to keys. {CommonProxyErrors.not_premium_user.value}")

        _metadata: Final = data_json.get("metadata")
        if not _metadata:
            data_json["metadata"] = {"tags": data_json["tags"]}
        else:
            data_json["metadata"]["tags"] = data_json["tags"]

        data_json.pop("tags")

    # Validate MCP servers in object_permission are within team scope
    _is_proxy_admin_caller: Final = user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN.value
    normalized_object_permission: Final = await validate_key_mcp_servers_against_team(
        object_permission=data_json.get("object_permission"),
        team_obj=team_table,
        prisma_client=prisma_client,
        is_proxy_admin=_is_proxy_admin_caller,
    )
    if normalized_object_permission is not None:

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Remove the "tags" field (or move it into metadata if you only need arbitrary metadata) for non-premium deployments
  2. Set a valid enterprise license: export LITELLM_LICENSE=<key> on the proxy and restart
  3. Get a trial key from https://www.litellm.ai/enterprise#trial if you want to evaluate the feature

Example fix

// before
curl -X POST http://localhost:4000/key/generate \
  -d '{"tags": ["team-a"]}'

// after: non-premium proxy stores tags as plain metadata
curl -X POST http://localhost:4000/key/generate \
  -d '{"metadata": {"tags": ["team-a"]}}'
Defensive patterns

Strategy: validation

Validate before calling

IS_ENTERPRISE = os.getenv("LITELLM_LICENSE") is not None  # mirror server config
if not IS_ENTERPRISE:
    payload.pop("tags", None)  # avoid the enterprise-only path entirely
requests.post(f"{PROXY}/key/generate", headers=AUTH, json=payload)

Try / catch

try:
    resp = requests.post(f"{PROXY}/key/generate", headers=AUTH, json=payload)
except requests.HTTPError as e:
    # ValueError on the server surfaces as 500 with this text
    if e.response.status_code == 500 and "Only premium users can add tags" in e.response.text:
        payload.pop("tags", None)
        resp = requests.post(f"{PROXY}/key/generate", headers=AUTH, json=payload)
    else:
        raise

Prevention

When it happens

Trigger: POST /key/generate with a top-level "tags": ["..."] field, on a proxy running without a valid LITELLM_LICENSE (premium_user is not True).

Common situations: Copying examples that use tags for cost tracking on the open-source proxy; testing locally without the enterprise license then deploying the same payload; upgrading from a trial license that expired.

Related errors


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