sgl-project/sglang · error · RuntimeError

Failed to find available port after {max_attempts} attempts

Error message

Failed to find available port after {max_attempts} attempts (started from port {original_port})

What it means

Raised by ServerArgs.settle_port when probing for a free TCP port: starting from the requested port it increments (wrapping past 60000 back into the 5000-6000 range with randomization) and after max_attempts probes still found no bindable port. It means the port range is saturated or the process lacks permission to bind.

Source

Thrown at python/sglang/multimodal_gen/runtime/server_args/server_args.py:2838

        original_port = port
        avoid = avoid or set()

        while attempts < max_attempts:
            if port not in avoid and is_port_available(port):
                if attempts > 0:
                    logger.info(
                        f"Port {original_port} was unavailable, using port {port} instead"
                    )
                return port

            attempts += 1
            if port < 60000:
                port += port_inc
            else:
                # Wrap around with randomization to avoid collision
                port = 5000 + random.randint(0, 1000)

        raise RuntimeError(
            f"Failed to find available port after {max_attempts} attempts "
            f"(started from port {original_port})"
        )

    @staticmethod
    def _extract_dynamic_component_map(
        unknown_args: list[str],
        *,
        option_prefixes: tuple[str, ...],
        alias_suffix: str,
    ) -> tuple[dict[str, str], list[str]]:
        component_values: dict[str, str] = {}
        remaining: list[str] = []
        i = 0
        while i < len(unknown_args):
            arg = unknown_args[i]
            key_part = arg.split("=", 1)[0] if "=" in arg else arg
            component = None

View on GitHub (pinned to 0132848349)

Solutions

  1. Free the occupied ports (stop stale servers: lsof -i :PORT / kill) or pass an explicit free --port / port argument.
  2. Pick a port in a range you know is open, verified beforehand with a socket bind test.
  3. If running many instances, stagger starting ports far apart or reduce concurrency of launches.
  4. Check container/host firewall or sysctl net.ipv4.ip_local_port_range if binds fail even on free ports.

Example fix

# before
python -m sglang.multimodal_gen.server --port 5000  # many shards, all collide
# after
python -m sglang.multimodal_gen.server --port $(python -c "import socket; s=socket.socket(); s.bind(('',0)); print(s.getsockname()[1]); s.close()")
Defensive patterns

Strategy: retry

Validate before calling

import socket

def free_port(start: int, attempts: int = 100) -> int:
    for p in range(start, start + attempts):
        with socket.socket() as s:
            if s.connect_ex(("127.0.0.1", p)) != 0:
                return p
    raise RuntimeError("no free port")

Try / catch

try:
    args = ServerArgs.from_cli_args(cli)
except RuntimeError as e:
    if "Failed to find available port" in str(e):
        args = ServerArgs.from_cli_args(cli + ["--port", str(free_port(20000))])
    else:
        raise

Prevention

When it happens

Trigger: Calling ServerArgs.from_cli_args / prepare_server_args on a machine where the candidate port range (port..port+max_attempts, or 5000-6000 after wrap) is fully occupied, e.g. many SGLang/multimodal_gen server instances already listening, or firewall/permission restrictions blocking binds.

Common situations: Launching multiple test workers or CI shards on one host that each auto-allocate ports; containers with very restricted ephemeral port ranges; a stale server still holding the port; port set below 1024 without root.

Related errors


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