{"record":{"id":"cfea35c3eb30fb3c","repo":"vllm-project/vllm","slug":"block-size-self-block-size-must-be-a-multiple","errorCode":null,"errorMessage":"block_size ({self.block_size}) must be a multiple of hash_block_size ({self.hash_block_size})","messagePattern":"block_size \\((.+?)\\) must be a multiple of hash_block_size \\((.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/data.py","lineNumber":180,"sourceCode":"        return self.build_key_string(\n            self.build_prefix(self.key_metadata), self.chunk_hash\n        )\n\n\nclass ChunkedTokenDatabase:\n    \"\"\"Maps token positions to store keys and GPU memory addresses.\"\"\"\n\n    def __init__(\n        self,\n        metadata: KeyMetadata,\n        block_size: int,\n        hash_block_size: int | None = None,\n    ):\n        self.metadata = metadata\n        self.block_size = block_size\n        self.hash_block_size = hash_block_size or block_size\n        if self.block_size % self.hash_block_size != 0:\n            raise ValueError(\n                f\"block_size ({self.block_size}) must be a multiple of \"\n                f\"hash_block_size ({self.hash_block_size})\"\n            )\n        self.kv_caches_base_addr: list[int] = []\n        self.block_len: list[int] = []\n        self._key_prefix = PoolKey.build_prefix(metadata)\n\n    def key_for(self, chunk_hash: BlockHash) -> str:\n        return PoolKey.build_key_string(self._key_prefix, chunk_hash.hex())\n\n    def set_kv_caches_base_addr(self, kv_caches_base_addr: list[int]):\n        self.kv_caches_base_addr = kv_caches_base_addr\n\n    def set_block_len(self, block_len: list[int]):\n        self.block_len = block_len\n\n    def prepare_value(\n        self, start: int, end: int, block_ids: list[int]","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/data.py#L162-L198","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pick hash_block_size that divides block_size exactly (e.g. 16 -> 1,2,4,8,16; block_size 7 -> 1 or 7)","Or omit hash_block_size from kv_connector_extra_config so it defaults to block_size","Check the effective cache_config.block_size of your model config before choosing a hash granularity"],"exampleFix":"# before\nkv_connector_extra_config={\"hash_block_size\": 12},  # block_size=16 -> ValueError\n\n# after\nkv_connector_extra_config={\"hash_block_size\": 8},   # divides 16\n# or simply omit the key","handlingStrategy":"validation","validationCode":"hbs = extra_config.get(\"hash_block_size\", block_size)\nif block_size % hbs != 0:\n    raise ValueError(f\"hash_block_size {hbs} must divide block_size {block_size}\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive hash_block_size from cache_config.block_size (power-of-two divisors)","Omit hash_block_size unless you specifically need finer hashing granularity","Print cache_config.block_size once at startup to confirm assumptions"],"tags":["mooncake","kv-transfer","block-size","config"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}