vllm-project/vllm · error · ValueError

numa_bind_cpus entries must not be empty.

Error message

numa_bind_cpus entries must not be empty.

What it means

Inside the numa_bind_cpus list validator, each entry must be a non-empty string before regex matching. An empty-string entry (e.g. from 'a,,b' splitting or a list like ['0-3', '']) is rejected because it is neither unset (None) nor a valid CPU list.

Source

Thrown at vllm/config/parallel.py:435

        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

    @model_validator(mode="after")
    def _validate_parallel_config(self) -> Self:
        if self._api_process_rank >= self._api_process_count:

View on GitHub (pinned to c794754062)

Solutions

  1. Remove empty segments: ensure every comma-separated entry is non-empty (no ',,' or trailing ',').
  2. If building the list in code, filter empties before passing: [s for s in parts if s].

Example fix

# before
vllm serve model --numa-bind-cpus 0-3,,8-11

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

Strategy: validation

Validate before calling

def clean_cpuset_list(entries: list[str]) -> list[str]:
    cleaned = [e.strip() for e in entries if e and e.strip()]
    if len(cleaned) != len(entries):
        raise SystemExit(f"Empty numa_bind_cpus entry in {entries}")
    return cleaned

Type guard

def no_empty_cpuset_entries(entries: list[str]) -> bool:
    return all(isinstance(e, str) and e for e in entries)

Prevention

When it happens

Trigger: Passing --numa-bind-cpus 0-3,,8-11 (double comma), or programmatically ['0-3', ''] / [''] after CSV splitting.

Common situations: String concatenation bugs that join lists with commas when one element is empty; trailing/duplicate commas in hand-written configs.

Related errors


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