{"record":{"id":"6848d57736260c1d","repo":"vllm-project/vllm","slug":"nnodes-1-can-only-be-set-when-distributed-execut","errorCode":null,"errorMessage":"nnodes > 1 can only be set when distributed executor backend is mp, uni or external_launcher.","messagePattern":"nnodes > 1 can only be set when distributed executor backend is mp, uni or external_launcher\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"vllm/config/parallel.py","lineNumber":968,"sourceCode":"                        if get_current_placement_group():\n                            backend = \"ray\"\n            self.distributed_executor_backend = backend\n            logger.debug(\"Defaulting to use %s for distributed inference\", backend)\n\n        if self.distributed_executor_backend is None and self.world_size == 1:\n            self.distributed_executor_backend = \"uni\"\n\n        if self.max_parallel_loading_workers is not None:\n            logger.warning(\n                \"max_parallel_loading_workers is currently \"\n                \"not supported and will be ignored.\"\n            )\n        allowed_backends = (\"mp\", \"uni\", \"external_launcher\")\n        if (\n            self.distributed_executor_backend not in allowed_backends\n            and self.nnodes > 1\n        ):\n            raise ValueError(\n                \"nnodes > 1 can only be set when distributed executor \"\n                \"backend is mp, uni or external_launcher.\"\n            )\n\n        if self.enable_eplb and self.eplb_config.communicator is None:\n            # Prefer NIXL when available: zero-copy RDMA reads, compatible\n            # with both async EPLB and elastic EP (deferred remote setup).\n            # Fallbacks: pynccl for elastic EP (stateless groups need it),\n            # torch_gloo for static EP.  torch_nccl is avoided because NCCL\n            # is incompatible with async EPLB (multi-stream conflicts) and\n            # batched isend/irecv hangs under high load.\n            # See https://github.com/pytorch/pytorch/issues/174288\n            from vllm.distributed.nixl_utils import is_nixl_available\n\n            if is_nixl_available():\n                self.eplb_config.communicator = \"nixl\"\n            elif self.enable_elastic_ep:\n                self.eplb_config.communicator = \"pynccl\"","sourceCodeStart":950,"sourceCodeEnd":986,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/config/parallel.py#L950-L986","documentation":"ParallelConfig rejects nnodes > 1 when the chosen distributed executor backend is not one of 'mp', 'uni', or 'external_launcher'. Multi-node execution in vLLM is only supported by those backends; Ray-based multi-node is configured through Ray itself (data_parallel_backend='ray'), not via nnodes, and other custom backends declare no multi-node support.","triggerScenarios":"Passing --nnodes 2 (or --data-parallel-size with nnodes>1) together with a distributed_executor_backend outside ('mp','uni','external_launcher'), e.g. backend='ray' with nnodes=2, or a custom Executor subclass with nnodes>1.","commonSituations":"User upgrades from an older vLLM where nnodes+ray was accepted; user mixes --distributed-executor-backend ray with --nnodes expecting Ray to honor it; scripts migrated from torchrun-style launchers keep --nnodes while switching backends.","solutions":["If using Ray for multi-node, drop --nnodes and let Ray manage placement: set --data-parallel-backend ray (or distributed_executor_backend ray) without nnodes.","If using multiprocessing multi-node, keep --distributed-executor-backend mp (default) with --nnodes/--node-rank.","If launching under an external launcher (e.g. torchrun/srun), use --distributed-executor-backend external_launcher with --nnodes.","For TPU SPMD, use backend 'uni' with nnodes."],"exampleFix":"# before\n--distributed-executor-backend ray --nnodes 2 --node-rank 0\n\n# after (Ray manages nodes itself)\n--distributed-executor-backend ray --tensor-parallel-size 2 --data-parallel-size 4","handlingStrategy":"validation","validationCode":"ALLOWED_MULTI_NODE = {\"mp\", \"uni\", \"external_launcher\"}\n\ndef validate_multi_node(backend: str | None, nnodes: int) -> None:\n    if nnodes > 1 and backend not in ALLOWED_MULTI_NODE:\n        raise SystemExit(\n            f\"nnodes={nnodes} requires backend in {ALLOWED_MULTI_NODE}; \"\n            \"for Ray multi-node drop --nnodes and set data_parallel_backend=ray.\"\n        )","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never combine --distributed-executor-backend ray with --nnodes; Ray schedules nodes itself.","Centralize executor-backend choice in one launch helper so backend/nnodes pairs are always consistent."],"tags":["parallelism","multi-node","ray","configuration"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}