sgl-project/sglang · error · ValueError

{port_name} has invalid port number {port}. Valid TCP port r

Error message

{port_name} has invalid port number {port}. Valid TCP port range is 0-{MAX_VALID_PORT}.

What it means

wait_port_available validates the port argument before its wait loop; anything outside 0-65535 raises immediately with the offending value. This is a caller bug (bad port arithmetic, unset env var parsed as -1, or a port literal typos like 70000) rather than a network condition.

Source

Thrown at python/sglang/srt/utils/network.py:69


MAX_VALID_PORT = 65535


def wait_port_available(
    port: int,
    port_name: str,
    timeout_s: Optional[int] = None,
    raise_exception: bool = True,
) -> bool:
    if timeout_s is None:
        # A killed server can hold its ports well past kill_process_tree()'s
        # return while GPU teardown completes (>30s observed on GB300), so CI
        # raises this via SGLANG_WAIT_PORT_TIMEOUT before relaunching a server
        # on the same port plan.
        timeout_s = int(os.environ.get("SGLANG_WAIT_PORT_TIMEOUT", "30"))
    if port < 0 or port > MAX_VALID_PORT:
        raise ValueError(
            f"{port_name} has invalid port number {port}. "
            f"Valid TCP port range is 0-{MAX_VALID_PORT}."
        )

    error_message = f"{port_name} at {port} is not available"
    for i in range(timeout_s):
        if is_port_available(port):
            return True

        if i > 10 and i % 5 == 0:
            process = find_process_using_port(port)
            if process is None:
                logger.warning(
                    f"The port {port} is in use, but we could not find the process that uses it."
                )
            else:
                pid = process.pid
                error_message = f"{port_name} is used by a process already. {process.name()=}' {process.cmdline()=} {process.status()=} {pid=}"

View on GitHub (pinned to 0132848349)

Solutions

  1. Fix the port computation so it stays within 0-65535 (clamp or reduce the base port).
  2. Check env vars feeding the port for garbage values (e.g., print/validate before launch).
  3. Use get_open_port() to allocate ephemeral ports instead of arithmetic on a fixed base.

Example fix

# before
port = args.port + rank * 1000  # overflows for large rank/port

# after
port = args.port + rank * 1000
assert 0 <= port <= 65535, f"port {port} out of range"
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(port, int) and 0 <= port <= 65535, f"bad port {port!r}"

Type guard

def is_valid_port(p) -> bool:
    return isinstance(p, int) and 0 <= p <= 65535

Prevention

When it happens

Trigger: init_new passing a derived port (base_port + dp_rank*size etc.) that overflowed 65535 or went negative, or a port string parsed incorrectly from an environment variable.

Common situations: Large --port plus --dp-size/--tp-size offsets exceeding 65535; port defaults of -1 used as 'unset' sentinel reaching this function; misparsed SGLANG_PORT env vars.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/63ac528aff7b68a5. Report an issue: GitHub.