sgl-project/sglang · warning · HTTPException

No transfer engine info for rank {rank}

Error message

No transfer engine info for rank {rank}

What it means

GET /get_transfer_engine_info returns HTTP 404 when the requested rank hasn't (yet) registered its transfer-engine info with the bootstrap server. Registration happens asynchronously per rank during startup, so early or out-of-order queries find no entry yet.

Source

Thrown at python/sglang/srt/entrypoints/engine_info_bootstrap_server.py:83

                logger.info(
                    f"Registered transfer engine info for tp_rank={tp_rank}, "
                    f"session_id={session_id}"
                )
                return PlainTextResponse("OK")
            except Exception as e:
                logger.error(f"Failed to register engine info: {e}")
                raise HTTPException(status_code=400, detail=str(e))

        @app.get("/get_transfer_engine_info")
        def get_transfer_engine_info(rank: int):
            if rank < 0:
                raise HTTPException(status_code=400, detail="Invalid rank parameter")

            with self.lock:
                info = self.transfer_engine_info.get(rank)

            if info is None:
                raise HTTPException(
                    status_code=404,
                    detail=f"No transfer engine info for rank {rank}",
                )

            return {"rank": rank, "remote_instance_transfer_engine_info": list(info)}

        config = uvicorn.Config(app, host=host, port=port, log_level="warning")
        self._server = uvicorn.Server(config)
        self._thread = threading.Thread(
            target=self._server.run,
            daemon=True,
        )
        self._thread.start()
        logger.info(f"EngineInfoBootstrapServer started on {host}:{port}")

    def close(self):
        self._server.should_exit = True
        self._thread.join(timeout=5)

View on GitHub (pinned to 0132848349)

Solutions

  1. Retry with backoff until the rank registers or a startup timeout expires — this is normally a race, not a permanent failure.
  2. Verify the target rank actually exists in this deployment's world size and that its worker is alive.
  3. Check the registering worker's logs if a rank never registers (it may have crashed — see its traceback).

Example fix

# before
r = requests.get(url, params={"rank": rank})
info = r.json()  # 404 -> JSONDecodeError

# after
for _ in range(60):
    r = requests.get(url, params={"rank": rank})
    if r.status_code == 200:
        info = r.json(); break
    time.sleep(1)
Defensive patterns

Strategy: retry

Validate before calling

def get_info(session, url, rank, attempts=60, delay=1.0):
    for _ in range(attempts):
        r = session.get(url, params={"rank": rank})
        if r.status_code == 200:
            return r.json()
        if r.status_code != 404:
            r.raise_for_status()
        time.sleep(delay)
    raise TimeoutError(f"rank {rank} never registered")

Try / catch

while True:
    r = requests.get(url, params={"rank": rank})
    if r.status_code == 200:
        return r.json()
    if r.status_code != 404:
        r.raise_for_status()
    time.sleep(1)

Prevention

When it happens

Trigger: Querying a rank before that rank's worker has completed its /register_transfer_engine_info call — e.g. polling too early during engine startup, or asking for a rank >= the number of registered workers.

Common situations: Startup race where consumers poll for info before producers register; querying a rank that crashed before registering; misconfigured world size making clients ask for nonexistent ranks.

Related errors


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