vllm-project/vllm · error · ValueError

block_size ({self.block_size}) must be a multiple of hash_bl

Error message

block_size ({self.block_size}) must be a multiple of hash_block_size ({self.hash_block_size})

What it means

KeyIndex maps token positions to Mooncake store keys; it requires the token block_size to be an exact multiple of hash_block_size (the granularity at which block hashes are computed, defaulting to block_size). The constructor raises immediately when block_size % hash_block_size != 0, because chunk boundaries would not align with hash boundaries.

Source

Thrown at vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/data.py:180

        return self.build_key_string(
            self.build_prefix(self.key_metadata), self.chunk_hash
        )


class ChunkedTokenDatabase:
    """Maps token positions to store keys and GPU memory addresses."""

    def __init__(
        self,
        metadata: KeyMetadata,
        block_size: int,
        hash_block_size: int | None = None,
    ):
        self.metadata = metadata
        self.block_size = block_size
        self.hash_block_size = hash_block_size or block_size
        if self.block_size % self.hash_block_size != 0:
            raise ValueError(
                f"block_size ({self.block_size}) must be a multiple of "
                f"hash_block_size ({self.hash_block_size})"
            )
        self.kv_caches_base_addr: list[int] = []
        self.block_len: list[int] = []
        self._key_prefix = PoolKey.build_prefix(metadata)

    def key_for(self, chunk_hash: BlockHash) -> str:
        return PoolKey.build_key_string(self._key_prefix, chunk_hash.hex())

    def set_kv_caches_base_addr(self, kv_caches_base_addr: list[int]):
        self.kv_caches_base_addr = kv_caches_base_addr

    def set_block_len(self, block_len: list[int]):
        self.block_len = block_len

    def prepare_value(
        self, start: int, end: int, block_ids: list[int]

View on GitHub (pinned to c794754062)

Solutions

  1. Pick hash_block_size that divides block_size exactly (e.g. 16 -> 1,2,4,8,16; block_size 7 -> 1 or 7)
  2. Or omit hash_block_size from kv_connector_extra_config so it defaults to block_size
  3. Check the effective cache_config.block_size of your model config before choosing a hash granularity

Example fix

# before
kv_connector_extra_config={"hash_block_size": 12},  # block_size=16 -> ValueError

# after
kv_connector_extra_config={"hash_block_size": 8},   # divides 16
# or simply omit the key
Defensive patterns

Strategy: validation

Validate before calling

hbs = extra_config.get("hash_block_size", block_size)
if block_size % hbs != 0:
    raise ValueError(f"hash_block_size {hbs} must divide block_size {block_size}")

Prevention

When it happens

Trigger: Passing kv_connector_extra_config['hash_block_size'] that does not divide the model/server block_size, e.g. block_size=16 with hash_block_size=12, or a model whose cache block size is 7/13 (non-power-of-two) combined with a hash_block_size tuned for power-of-two blocks.

Common situations: Tuning hash granularity for partial-tail offloads without checking the server block size; models with odd block sizes (some SSM/hybrid or DeepSeek-style caches) where the default hash_block_size assumption breaks.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/cfea35c3eb30fb3c. Report an issue: GitHub.