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
- List existing servers first and pick an unused server_id.
- If the server already exists and you want to change it, use the update path instead of create.
- 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
- Make provisioning scripts create-or-update, not create-only.
- Use list to reserve/derive unique ids before posting.
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
- MCP server is already rejected.
- MCP Server with id {server_id} not found
- User does not have permission to view mcp server with id {se
- User does not have permission to create mcp servers. You can
- MCP Server with id {payload.server_id} is special and cannot
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/efeb84cfafa049ca.
Report an issue: GitHub.