sgl-project/sglang · error · ValueError

LogicalHostPool allocation must be page-aligned, got need_si

Error message

LogicalHostPool allocation must be page-aligned, got need_size={need_size}, page_size={self.page_size}

What it means

LogicalHostPool.alloc validates that every allocation request is a multiple of the pool's page_size, since it hands out page-aligned token slots. A non-aligned need_size raises ValueError immediately (before any capacity check).

Source

Thrown at python/sglang/srt/mem_cache/memory_pool_host.py:112

    def available_size(self):
        return len(self.free_slots) + self.num_release_slots

    def _merge_release_slots(self):
        if self.num_release_slots == 0:
            return

        if len(self.free_slots) == 0 and len(self.release_slots) == 1:
            self.free_slots = self.release_slots[0]
        else:
            self.free_slots = torch.cat([self.free_slots, *self.release_slots])

        self.release_slots = []
        self.num_release_slots = 0

    @synchronized
    def alloc(self, need_size: int) -> Optional[torch.Tensor]:
        if need_size % self.page_size != 0:
            raise ValueError(
                "LogicalHostPool allocation must be page-aligned, "
                f"got need_size={need_size}, page_size={self.page_size}"
            )
        if need_size > self.available_size():
            return None

        if need_size > len(self.free_slots):
            self._merge_release_slots()

        select_index = self.free_slots[:need_size]
        self.free_slots = self.free_slots[need_size:]
        return select_index

    @synchronized
    def free(self, indices: torch.Tensor) -> int:
        if len(indices) % self.page_size != 0:
            raise ValueError(
                "LogicalHostPool free must be page-aligned, "

View on GitHub (pinned to 0132848349)

Solutions

  1. Round the request up to a page multiple: need = ((n + page_size - 1) // page_size) * page_size
  2. Verify the pool was configured with the page_size you expect before allocating
  3. Check available_size() after rounding, since rounding up may exceed free slots

Example fix

# before
idx = pool.alloc(len(req.input_ids))

# after
ps = pool.page_size
need = ((len(req.input_ids) + ps - 1) // ps) * ps
idx = pool.alloc(need)
Defensive patterns

Strategy: validation

Validate before calling

need = ((need_size + pool.page_size - 1) // pool.page_size) * pool.page_size
assert need % pool.page_size == 0

Type guard

null

Try / catch

try:
    out = pool.alloc(need_size)
except ValueError:
    out = pool.alloc(round_up(need_size, pool.page_size))

Prevention

When it happens

Trigger: Calling pool.alloc(need_size) where need_size % page_size != 0, e.g. alloc(len(token_ids)) with a raw sequence length like 37 against page_size=16.

Common situations: Callers passing un-padded sequence lengths directly; code that assumed token-granular (page_size=1) allocation later run with a paged host config.

Related errors


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