sgl-project/sglang · error · ValueError

{port_name} at {port} is not available in {timeout_s} second

Error message

{port_name} at {port} is not available in {timeout_s} seconds. {error_message}

What it means

wait_port_available polls a port once per second for timeout_s (default 30, overridable via SGLANG_WAIT_PORT_TIMEOUT) and raises if it never becomes bindable. Usually the previous server process is still holding the port — the comment notes GPU teardown can keep ports held >30s on GB300-class hardware.

Source

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

        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=}"
                logger.info(
                    f"port {port} is in use. Waiting for {i} seconds for {port_name} to be available. {error_message}"
                )
        time.sleep(1)

    if raise_exception:
        raise ValueError(
            f"{port_name} at {port} is not available in {timeout_s} seconds. {error_message}"
        )
    return False


def _get_addrinfos_for_bind(host=None, port=0):
    """Return deduplicated addrinfo tuples for binding (one per address family).

    Args:
        host: Bind address. None (with AI_PASSIVE) resolves to wildcard
              addresses (0.0.0.0 / ::) suitable for accepting on all interfaces.
        port: Port number. 0 lets the OS assign an available ephemeral port.

    Flags:
        AI_ADDRCONFIG — only return families actually configured on this host.
        AI_PASSIVE    — return wildcard addresses suitable for bind().

    Falls back to AF_INET if getaddrinfo fails (e.g. DNS misconfiguration).

View on GitHub (pinned to 0132848349)

Solutions

  1. Raise the budget: export SGLANG_WAIT_PORT_TIMEOUT=120.
  2. Ensure the old process fully exits before relaunch (wait on PID, check nvidia-smi for leftover CUDA contexts).
  3. Use a different port / let sglang pick a free port via get_open_port.

Example fix

# before
kill_process_tree(old_pid); relaunch(port=30000)

# after
kill_process_tree(old_pid)
import os; os.environ["SGLANG_WAIT_PORT_TIMEOUT"] = "120"
relaunch(port=30000)
Defensive patterns

Strategy: retry

Validate before calling

import socket

def port_free(port: int) -> bool:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        return s.connect_ex(("127.0.0.1", port)) != 0

Try / catch

for attempt in range(3):
    try:
        wait_port_available(port, raise_exception=True)
        break
    except ValueError:
        time.sleep(10)
else:
    raise

Prevention

When it happens

Trigger: init_new relaunching a server on the same port plan while the old process's sockets are still in TIME_WAIT/held during GPU teardown; or another service occupying the port.

Common situations: CI restarting servers quickly; kill_process_tree returning before the OS releases ports; port collisions between sglang instances or with other services.

Understand the failure class

Related errors


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