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
- Round the request up to a page multiple: need = ((n + page_size - 1) // page_size) * page_size
- Verify the pool was configured with the page_size you expect before allocating
- 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
- Centralize a round_up-to-page helper and use it for every alloc call
- Check available_size() after rounding up
- Unit-test alloc paths with page_size > 1
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
- LogicalHostPool size must be page-aligned, got size={size},
- LoRA adapter {lora_ref.lora_name} with rank {lora_config.r}
- Out of memory. Try to lower your batch size.\nTry to allocat
- Unsupported layout: {self.layout}
- {context} req_to_token table is empty but gather mask is non
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/ba4db60e324417e3.
Report an issue: GitHub.