vllm-project/vllm · error · ValueError

numa_bind_cpus must not be empty.

Error message

numa_bind_cpus must not be empty.

What it means

ParallelConfig's field validator for numa_bind_cpus mirrors the nodes validator: None means unset, but an explicitly empty list is rejected because binding to zero CPU sets is meaningless. Each list entry is a numactl CPU-list string.

Source

Thrown at vllm/config/parallel.py:431

    @field_validator("numa_bind_nodes")
    @classmethod
    def _validate_numa_bind_nodes(cls, value: list[int] | None) -> list[int] | None:
        if value is None:
            return None
        if not value:
            raise ValueError("numa_bind_nodes must not be empty.")
        if any(node < 0 for node in value):
            raise ValueError("numa_bind_nodes must contain non-negative integers.")
        return value

    @field_validator("numa_bind_cpus")
    @classmethod
    def _validate_numa_bind_cpus(cls, value: list[str] | None) -> list[str] | None:
        if value is None:
            return None
        if not value:
            raise ValueError("numa_bind_cpus must not be empty.")

        for cpuset in value:
            if not cpuset:
                raise ValueError("numa_bind_cpus entries must not be empty.")
            if not _NUMACTL_CPUSET_PATTERN.fullmatch(cpuset):
                raise ValueError(
                    "numa_bind_cpus entries must use numactl CPU list syntax, "
                    "for example '0-3' or '0,2,4-7'."
                )
            for part in cpuset.split(","):
                if "-" not in part:
                    continue
                start_str, end_str = part.split("-", 1)
                if int(start_str) > int(end_str):
                    raise ValueError(
                        f"numa_bind_cpus ranges must be ascending, but got '{cpuset}'."
                    )
        return value

View on GitHub (pinned to c794754062)

Solutions

  1. Omit --numa-bind-cpus when CPU pinning is not wanted.
  2. Otherwise pass at least one numactl CPU list, e.g. --numa-bind-cpus 0-3.
  3. Guard the flag in your launch template: only render it when the variable is non-empty.

Example fix

# before
vllm serve model --numa-bind-cpus "${CPUS}"  # CPUS="" -> []

# after
vllm serve model --numa-bind-cpus 0-3,8-11
Defensive patterns

Strategy: validation

Validate before calling

def normalize_numa_cpus(v: list[str] | None) -> list[str] | None:
    return None if not v else v

Prevention

When it happens

Trigger: Passing --numa-bind-cpus with an empty value that parses to []; template interpolation of an empty env var; Python code ParallelConfig(numa_bind_cpus=[]).

Common situations: Same templating failure as numa_bind_nodes: charts/scripts emitting the flag unconditionally with an empty variable.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/9c0fe3d3f7b327fd. Report an issue: GitHub.