VLLM · GHSA-q9v9-qpjp-fc24 · AI agents & MCP
FIX → 0.33.0
When vLLM runs with --skip-tokenizer-init, a single unauthenticated request with a large prompt token id makes the shared EngineCore crash. The crash takes the engine and API server down for every user until the process restarts.
first public Nov 2, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Servers running vLLM 0.28.0 up to but not including 0.33.0 with --skip-tokenizer-init, which is used for pre-tokenized, token-in-token-out and RL serving. Deployments with a tokenizer enabled are not covered by this advisory's description. The OpenAI-compatible server has no auth by default, so any reachable client can send the request.
Not affected if auth-required, tokenizer-enabled, vllm-0.33.0-or-later, vllm-below-0.28.0
Who cares llm-serving, python, self-hosted, vllm
pip show vllm; affected range is >= 0.28.0 and < 0.33.0.--skip-tokenizer-init.Upgrade to 0.33.0
A single unauthenticated request with an out-of-range prompt token id crashes
the shared EngineCore (and the API-server process) when vLLM is served with
--skip-tokenizer-init, denying service to all tenants until the process is
restarted.
The vocab-range validation added for GHSA-25q3-v2hm-8vpf lives in
InputProcessor._validate_model_input but is gated on tokenizer is not None.
--skip-tokenizer-init is the mode where the client is expected to send raw
token ids (pre-tokenized / token-in-token-out / RL serving), and there is no
tokenizer, so the check is skipped entirely. The OpenAI /v1/completions
prompt field only constrains integer ids from below (Field(ge=0)), so a
large positive id passes all validation, reaches the embedding as an index, and
raises out of the model forward. EngineCore treats that as fatal and shuts down.
The same gap reopens the /v1/embeddings and /pooling paths that GHSA-25q3
originally covered, whenever the tokenizer is disabled.
Verified against main at HEAD (2026-09-15).
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
vllm0.33.0dc89fdfb0evllm/v1/engine/input_processor.py, _validate_model_input:
if prompt_ids and tokenizer is not None: # <- skipped when tokenizer is None
...
if min_input_id < 0: raise VLLMValidationError("... out of vocabulary")
if max_input_id > max(tokenizer.max_token_id, model_vocab_size - 1):
raise VLLMValidationError("... out of vocabulary")
Reachability (unauthenticated; the OpenAI server has no auth by default):
/v1/completions (prompt = list[int], Field(ge=0) only, no upper bound)
-> InputProcessor.process_inputs -> _validate_model_inputs
-> _validate_model_input # tokenizer is None -> vocab check skipped
-> model forward -> embedding index out of range -> exception
EngineCore._process_engine_step -> run_busy_loop (no per-step guard)
-> run_engine_core: "EngineCore encountered a fatal error" -> _send_engine_dead
The busy loop has no per-request guard around the model step, so the exception is fatal for the whole engine, not scoped to the offending request.
Unauthenticated remote denial of service (availability): one request
permanently takes down the shared engine for all tenants, on any deployment run
with --skip-tokenizer-init (pre-tokenized / token-in-token-out / RL serving).
Same class as GHSA-25q3-v2hm-8vpf (High), whose remediation did not cover the
tokenizer-disabled path. CWE-20 / CWE-1284 / CWE-248.
Run the vocab-range check whenever prompt ids are present, not only when a
tokenizer exists. When the tokenizer is disabled, use model_config .get_vocab_size() - 1 as the upper bound; otherwise keep the existing
max(tokenizer.max_token_id, model_vocab_size - 1) bound. This validation is implemented by the merged fix.
Reported by Matteo Atkinson (matteoatkinson@gmail.com), with AI assistance.
A fix for this was introduced in https://github.com/vllm-project/vllm/pull/62911.