vllm-project/vllm · error · HTTPException
Invalid keys format
Error message
Invalid keys format
What it means
HTTP 400 from the HF3FS metadata server's batch_key_exists endpoint when the POST body's 'keys' field is present but not a JSON list (it defaults to [] when absent, so only a wrong-typed value triggers this). The server validates the shape before touching state, so nothing is mutated when this is raised. It indicates the client serialized the keys array incorrectly.
Solutions
- Send 'keys' as a JSON array, e.g. {'keys': ['sess|block0', 'sess|block1']}.
- Omitting 'keys' entirely is also accepted (defaults to an empty list) if you only want a no-op check.
- Align connector client and metadata server versions if the wire format changed.
Example fix
// before
{"keys": "sess|blk"}
// after
{"keys": ["sess|blk"]} Defensive patterns
Strategy: validation
Validate before calling
assert isinstance(keys, list) and all(isinstance(k, str) for k in keys)
client.post("keys/batch_key_exists", json={"keys": keys}) Type guard
def is_key_list(v) -> bool:
return isinstance(v, list) and all(isinstance(k, str) for k in v) Prevention
- Normalize keys to strings at the client boundary
- Reuse the provided client class rather than raw requests
When it happens
Trigger: POST to the key-existence route with {'keys': 'my_key'} or {'keys': {'k': 1}} instead of {'keys': ['my_key']}; sending a JSON string body that decodes to a non-list.
Common situations: Client code that json.dumps a single key instead of a list of keys; schema drift between connector and metadata server versions; ad-hoc curl tests with malformed bodies.
Related errors
- Invalid request format: need 'rank' and 'confirmations'
- Invalid initialization parameters
- Invalid request format: need 'rank' and 'keys'
- Allocation failed
- Confirmation failed
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/87efbf05d3b370fb.
Report an issue: GitHub.
Appendix: source
Thrown at vllm/distributed/kv_transfer/kv_connector/v1/hf3fs/hf3fs_metadata_server.py:350
try:
self.state.confirm_write_for_keys(rank, confirmations, pages_to_release)
return Response(status_code=204)
except Exception as e:
logger.error("Confirm write for keys failed: %s", e)
raise HTTPException(
status_code=500, detail=f"Confirmation failed: {str(e)}"
) from e
async def batch_key_exists(self, request: Request):
"""Check if multiple keys exist in metadata."""
data = await self._read_json(request)
keys = data.get("keys", [])
if not isinstance(keys, list):
raise HTTPException(status_code=400, detail="Invalid keys format")
try:
exists_results = self.state.batch_key_exists(keys)
return self._json_response({"exists": exists_results})
except Exception as e:
raise HTTPException(
status_code=500, detail=f"Key existence check failed: {str(e)}"
) from e
async def get_key_locations(self, request: Request):
"""Get page indices for keys on a specific rank."""
data = await self._read_json(request)
rank = data.get("rank")
keys = data.get("keys", [])
# Validate input format
if rank is None or not isinstance(keys, list):
raise HTTPException(View on GitHub (pinned to c794754062)