[Bugfix][Elastic EP] Reject scale below the minimum data parallel size (#52702)

Signed-off-by: Itay Etelis <itay.etelis@ibm.com> Co-authored-by: Itay Etelis <itay.etelis@ibm.com>

Itay Etelis committed Aug 19, 2026 at 04:37 UTC d36cc4254eb6f745427e9bd328aab5ac34e5cb7e
2 files changed +16 -2
vllm/entrypoints/serve/elastic_ep/api_router.py
+2
@@ -75,6 +75,8 @@ async def scale_elastic_ep(raw_request: Request):
75 detail="Scale failed due to request drain timeout "
76 f"after {drain_timeout} seconds",
77 ) from e
78 + except ValueError as e:
79 + raise HTTPException(status_code=400, detail=str(e)) from e
80 except Exception as e:
81 logger.error("Scale failed: %s", e)
82 raise HTTPException(status_code=500, detail="Scale failed") from e
vllm/v1/engine/core_client.py
+14 -2
@@ -1637,9 +1637,21 @@ class DPLBAsyncMPClient(DPAsyncMPClient):
1637 )
1638 parallel_config = self.vllm_config.parallel_config
1639 num_experts = self.vllm_config.model_config.get_num_experts()
1640 - num_redundant_experts = (
1640 + num_physical_experts = (
1641 num_experts + parallel_config.eplb_config.num_redundant_experts
1642 - ) * new_data_parallel_size // cur_data_parallel_size - num_experts
1642 + )
1643 + num_redundant_experts = (
1644 + num_physical_experts * new_data_parallel_size // cur_data_parallel_size
1645 + - num_experts
1646 + )
1647 + if num_redundant_experts < 0:
1648 + # Scaling keeps physical experts per engine fixed, so below this
1649 + # size the logical experts no longer fit.
1650 + raise ValueError(
1651 + f"Cannot scale to data_parallel_size {new_data_parallel_size}, "
1652 + f"minimum is "
1653 + f"{-(-num_experts * cur_data_parallel_size // num_physical_experts)}"
1654 + )
1655 if new_data_parallel_size < cur_data_parallel_size:
1656 await self._prepare_scale_down_elastic_ep(new_data_parallel_size)
1657 else: