{"record":{"id":"7f8c8e24da729460","repo":"mlflow/mlflow","slug":"permission-denied","errorCode":"PERMISSION_DENIED","errorMessage":"Permission denied.","messagePattern":"Permission denied\\.","errorType":"error_code","errorClass":"MlflowException","httpStatus":403,"severity":"error","filePath":"mlflow/server/mcp_server_api.py","lineNumber":564,"sourceCode":"\n\ndef _ensure_version_create_parent_access(\n    store, name: str, username: str | None, request: Request\n) -> None:\n    if not getattr(request.state, \"mcp_server_parent_auto_created\", False):\n        return\n\n    try:\n        store.create_mcp_server(name=name, created_by=username)\n    except MlflowException as e:\n        if e.error_code != ErrorCode.Name(RESOURCE_ALREADY_EXISTS):\n            raise\n        request.state.mcp_server_parent_auto_created = False\n        can_update_existing = getattr(\n            request.state, \"mcp_server_can_update_existing_recheck\", lambda: False\n        )\n        if not can_update_existing():\n            raise MlflowException(\"Permission denied.\", error_code=PERMISSION_DENIED)\n\n\ndef _update_mcp_access_endpoint_kwargs(\n    server_name: str, endpoint_id: str, body: UpdateMCPAccessEndpointRequest\n) -> dict[str, Any]:\n    kwargs: dict[str, Any] = {\"server_name\": server_name, \"endpoint_id\": endpoint_id}\n    provided_fields = body.model_fields_set\n    for field_name in (\"server_version\", \"server_alias\", \"url\"):\n        if field_name in provided_fields:\n            kwargs[field_name] = getattr(body, field_name)\n    if \"transport_type\" in provided_fields:\n        kwargs[\"transport_type\"] = (\n            None if body.transport_type is None else _parse_transport_type(body.transport_type)\n        )\n    return kwargs\n\n\nmcp_server_router = APIRouter(tags=[\"MCP Server Registry\"])","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/mlflow/mlflow/blob/6a27f2decc0b76eb1b54af31849784addb357dbc/mlflow/server/mcp_server_api.py#L546-L582","documentation":"MLflow raises PERMISSION_DENIED when auto-creation of the parent MCP server registry entry is not permitted during create_mcp_server_version. If the parent did not exist and was created on the fly, but the caller lacks update permission on the (re-checked) existing parent, the operation is denied to prevent privilege escalation via auto-create.","triggerScenarios":"create_mcp_server_version where the parent server record does not exist (auto-create path runs), then the can_update_existing recheck finds a parent was created concurrently by another request and the current user lacks update permission on it.","commonSituations":"Race between two clients creating the same server version simultaneously; users with create-but-not-update permissions calling version creation for a server they do not own.","solutions":["Have an admin grant the user UPDATE permission on the parent MCP server.","Retry the request - if the parent now exists and you have access, the create may succeed via the normal path.","Create the parent MCP server explicitly with adequate permissions before creating versions.","Check workspace/registry permission configuration to ensure the role includes update on existing servers."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import mlflow\nfrom mlflow.exceptions import MlflowException\n\ndef can_create_version(name: str) -> bool:\n    try:\n        mlflow.mcp_server.get_mcp_server(name)\n        return True\n    except MlflowException:\n        return False  # will need auto-create/update permission","typeGuard":"def has_update_permission(server) -> bool:\n    return getattr(server, \"can_update\", False) or getattr(server, \"user_can_update\", False)","tryCatchPattern":"from mlflow.exceptions import MlflowException\ntry:\n    client.create_mcp_server_version(name, body)\nexcept MlflowException as e:\n    if e.error_code == \"PERMISSION_DENIED\":\n        request_admin_grant(\"UPDATE\", resource=name)  # escalate via admin, not retry-spam","preventionTips":["Verify the caller's permission level on the parent server before automated version creation","Avoid concurrent first-time creates of the same server; create the parent once up front","Use a service principal with both create and update scopes for CI pipelines"],"tags":["permissions","mcp-server","race-condition"],"backgroundTag":"permission-denied","analyzedSha":"6a27f2decc0b76eb1b54af31849784addb357dbc","analyzedAt":"2026-08-29T20:54:51.419Z","schemaVersion":2},"datasetVersion":"2026-08-29T22:17:34.462Z"}