BerriAI/litellm · error · HTTPException

MCP Server with id {payload.server_id} already exists. Canno

Error message

MCP Server with id {payload.server_id} already exists. Cannot create another.

What it means

Returned (400) by the create MCP server endpoint after get_mcp_server finds an existing row with the same payload.server_id — MCP server ids must be unique. The check only runs when server_id is provided; it fires before the payload's lifecycle fields are reset to active and before the DB write.

Source

Thrown at litellm/proxy/management_endpoints/mcp_management_endpoints.py:1564

                    "error": "User does not have permission to create mcp servers. You can only create mcp servers if you are a PROXY_ADMIN."
                },
            )

        # Block reserved special server IDs
        if (
            SpecialMCPServerName.all_team_servers == payload.server_id
            or SpecialMCPServerName.all_proxy_servers == payload.server_id
        ):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail={"error": f"MCP Server with id {payload.server_id} is special and cannot be used."},
            )

        if payload.server_id is not None:
            # fail if the mcp server with id already exists
            mcp_server: Final = await get_mcp_server(prisma_client, payload.server_id)
            if mcp_server is not None:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail={"error": f"MCP Server with id {payload.server_id} already exists. Cannot create another."},
                )

        # TODO: audit log for create

        # Admin-created servers are always active — clear any submission lifecycle
        # fields the caller may have provided to prevent fake entries appearing in
        # the submissions queue.
        payload.approval_status = MCPApprovalStatus.active
        payload.submitted_by = None
        payload.submitted_at = None

        # The database write is the commit point: if it fails nothing was
        # persisted and the request is a genuine failure.
        try:
            new_mcp_server: Final = await create_mcp_server(
                prisma_client,

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. List existing servers first and pick an unused server_id.
  2. If the server already exists and you want to change it, use the update path instead of create.
  3. Make scripts idempotent: on this 400, fall through to update/skip instead of failing.

Example fix

# before
requests.post(f"{PROXY}/v1/mcp/server", headers=AUTH, json=payload).raise_for_status()

# after: create-or-update on id collision
resp = requests.post(f"{PROXY}/v1/mcp/server", headers=AUTH, json=payload)
if resp.status_code == 400 and "already exists" in resp.text:
    resp = requests.put(f"{PROXY}/v1/mcp/server", headers=AUTH, json=payload)
resp.raise_for_status()
Defensive patterns

Strategy: validation

Validate before calling

existing = requests.get(f"{PROXY}/v1/mcp/server/{payload['server_id']}", headers=AUTH)
if existing.status_code == 200:
    action = "update"  # switch to the update path instead of create
else:
    action = "create"

Try / catch

try:
    create_server(payload)
except HTTPError as e:
    if e.response.status_code == 400 and "already exists" in e.response.text:
        update_server(payload)  # idempotent provision
    else:
        raise

Prevention

When it happens

Trigger: POST create with a server_id that already exists in the MCP server table; re-running a setup script that uses fixed ids; creating a server whose id collides with a config-defined server already loaded into the DB.

Common situations: Idempotent-looking provisioning scripts that re-post the same definition; retrying a create that actually succeeded; adopting a naming scheme that collides with an existing entry.

Related errors


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