sgl-project/sglang · error · ValueError
Unregistered UMBP hybrid pool: {}
Error message
Unregistered UMBP hybrid pool: {} What it means
During hybrid (MLA/MHA) page key composition, the pool name on a PoolTransfer was not found in registered_pools, so per-page suffix keys cannot be built. Each transfer must reference a pool registered with the UMBP store.
Source
Thrown at python/sglang/srt/mem_cache/storage/umbp/umbp_store.py:1245
# logical KV anchor that owns only page indices. The controller registers
# each real pool through register_mem_host_pool_v2() and drives storage
# via these _v2 methods, one PoolTransfer per pool. This mirrors the proven
# MooncakeStore / HiCacheHF3FS design, specialized for UMBP's page_first,
# single-object-per-page layout (each page -> exactly one storage object).
# ------------------------------------------------------------------
def _get_hybrid_page_component_keys(self, page_keys, transfer: PoolTransfer):
"""Map per-page logical keys to per-object storage keys for a side pool.
For UMBP every registered side pool is page_first and stores one object
per page (MLA: a single K object; MHA: a K and a V object), so the
component-key count is an exact multiple of the page count. The pool
name is embedded in the suffix so pages that share a hash across pools
never collide.
"""
pool_name = transfer.name
host_pool = self.registered_pools.get(pool_name)
if host_pool is None:
raise ValueError(f"Unregistered UMBP hybrid pool: {pool_name}")
if self.is_mla_backend:
# Single compressed object per page.
suffixes = [f"_{self.mla_suffix}_{pool_name}"]
elif getattr(host_pool, "v_buffer", None) is not None:
# Ordinary MHA side pool mirrors a K/V pool.
suffixes = [
f"_{self.mha_suffix}_{pool_name}_k",
f"_{self.mha_suffix}_{pool_name}_v",
]
else:
suffixes = [f"_{self.mha_suffix}_{pool_name}"]
key_multiplier = len(suffixes)
component_keys = [
f"{page_key}{suffix}" for page_key in page_keys for suffix in suffixes
]
return component_keys, key_multiplierView on GitHub (pinned to 0132848349)
Solutions
- Ensure every pool referenced by transfers is registered (registered_pools) before issuing batch I/O
- Check for name typos/mismatch between the pool registration and the PoolTransfer construction
- Register pools during model runner init before scheduler-driven I/O starts
Example fix
// before transfer = PoolTransfer(name='kv_pool_mha', ...) store.batch_get_v2([transfer]) // after store.registered_pools['kv_pool_mha'] = host_pool # ensure registered first transfer = PoolTransfer(name='kv_pool_mha', ...) # must match exactly store.batch_get_v2([transfer])
Defensive patterns
Strategy: validation
Validate before calling
assert transfer.name in store.registered_pools, f"pool {transfer.name!r} not registered" Type guard
def transfer_pool_registered(store, t) -> bool:
return t.name in store.registered_pools Prevention
- Register all hybrid pools before issuing batch I/O
- Add init-time assertions enumerating required pool names
When it happens
Trigger: Calling batch_exists_v2 or _batch_io_v2 with a PoolTransfer whose .name doesn't match any registered host pool (typo, unregistered pool, or registration skipped).
Common situations: Adding a new hybrid pool but forgetting to register it with the UMBP store; renaming pools between components; race where transfer is built before registration completes.
Related errors
- mori.umbp is not available. Build mori with BUILD_UMBP=ON or
- UMBPHostTensorAllocator only supports CPU host memory, got d
- UMBPHostMemAllocator.alloc({} bytes) failed (requested_backi
- extra_config[{!r}] must be a boolean-like value (true/false,
- {} must not be None
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/ce9397fa5e0e4c28.
Report an issue: GitHub.