Every CVE Search/ Get API key

CVE-2026-54234

vLLM: Remote DoS in vLLM via Invalid Recovered Token Reinjection

7.5 HighFix available

vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs. Prior to 0.24.0, a frontend-legal multi-request speculative decoding workload can cause the rejection sampler to produce a recovered token equal to the model vocabulary size boundary value, which is then converted to negative one when the engine selects the next live token for a request and is written back into the drafter's input ids; that out-of-vocabulary value is later consumed by the model's embedding and attention path and crashes the engine worker with a GPU device-side assertion. The same triggering request sequence is reachable through the public gRPC Generate and Abort endpoints, so a remote client that can send generation requests can crash the shared engine worker, aborting concurrent requests and causing a service-wide denial of service for other clients of the deployment until the worker is restarted. This issue is fixed in version 0.24.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.62%Up 0.3 points since Jul 7, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

vLLM: Remote DoS in vLLM via Invalid Recovered Token Reinjection

vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs. Prior to 0.24.0, a frontend-legal multi-request speculative decoding workload can cause the rejection sampler to produce a recovered token equal to the model vocabulary size boundary value, which is then converted to negative one when the engine selects the next live token for a request and is written back into the drafter's input ids; that out-of-vocabulary value is later consumed by the model's embedding and attention path and crashes the engine worker with a GPU device-side assertion. The same triggering request sequence is reachable through the public gRPC Generate and Abort endpoints, so a remote client that can send generation requests can crash the shared engine worker, aborting concurrent requests and causing a service-wide denial of service for other clients of the deployment until the worker is restarted. This issue is fixed in version 0.24.0.

Record
CVE-2026-54234
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-20, CWE-1284
Updated
2026-11-02
EUVDEUVD-2026-41921 7.5

vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs. Prior to 0.24.0, a frontend-legal multi-request speculative decoding workload can cause the rejection sampler to produce a recovered token equal to the model vocabulary size boundary value, which is then converted to negative one when the engine selects the next live token for a request and is written back into the drafter's input ids; that out-of-vocabulary value is later consumed by the model's embedding and attention path and crashes the engine worker with a GPU device-side assertion. The same triggering request sequence is reachable through the public gRPC Generate and Abort endpoints, so a remote client that can send generation requests can crash the shared engine worker, aborting concurrent requests and causing a service-wide denial of service for other clients of the deployment until the worker is restarted. This issue is fixed in version 0.24.0.

Record
EUVD-2026-41921
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-8wr5-jm2h-8r4f 7.5

vLLM has Remote DoS via Invalid Recovered Token Reinjection

Summary

A frontend-legal multi-request speculative workload can make vLLM produce an out-of-vocabulary recovered token equal to vocab_size, convert that value to -1 when choosing the next live token for a request, and then feed that -1 back into the next drafter input ids. On Qwen3 GPTQ this reaches the worker-side drafting / attention path and crashes the engine with a GPU device-side assert.

The same issue is reachable through the public gRPC request surface by sending a specific overlapping Generate / Abort sequence.

Impact

  • A remote client that can send public gRPC generation requests can crash the shared vLLM engine worker
  • The triggering request sequence aborts concurrent requests and prevents later requests from completing until the worker is restarted
  • In shared deployments, this is a service-wide denial of service for other clients, not just a failure isolated to the attacking requests
  • The failure is reproducible, so repeated request sequences can sustain the outage

Affected version

  • Confirmed on vLLM 0.17.1
  • Earlier and later versions have not been checked yet in this report

Repro model

  • Official Hugging Face repo:
  • Anyone wants to reproduce the bug with my PoC scripts should download Qwen3-0.6B-GPTQ-Int8 first

Trigger chain

  1. A legal multi-request speculative workload keeps structured-output state, speculative decoding, overlap, and request cancellation active in the same live engine.
  2. During rejection sampling, vLLM produces a recovered token equal to the model vocab_size boundary value.
  3. That recovered token appears in position 0 of the sampled speculative row for a live request. The same row also contains trailing padding entries equal to -1, but those padding entries are not the key fault by themselves.
  4. The next-token preparation step treats the position-0 recovered token as the real next token for that request and converts that out-of-vocabulary value to -1.
  5. The drafter writes that converted -1 back into the live next-step input-id row for the request.
  6. The drafting / embedding / attention path later consumes that live invalid token and the worker crashes on GPU.

Details

Simple example

The important distinction is:

  • trailing -1 values in a speculative row can be ordinary padding
  • the bug appears when the first live token for a request becomes 151936 == vocab_size, and that live token is then converted into -1

In simplified form, the bad transition looks like this:

sampled speculative row:
[151936, -1, -1, -1, ...]

At this point, the trailing -1 values are only padding. The critical problem is that the first position holds 151936, which is out of vocabulary and is being treated as the request's real next token.

Then vLLM prepares the next-token buffer:

next_token_ids:
[-1, ...]

Finally, that converted -1 is written back into the live model input ids:

input_ids_after:
[-1, 0, 0, 0, ...]

The crash happens because the live next token became -1 and was later consumed by the drafting / embedding / attention path, not merely because the speculative row contained padded -1 entries.

Trigger path in code

  1. The workload is frontend-legal. The requests use normal SamplingParams features such as structured outputs, stop, bad_words, min_tokens, and streaming overlap. No malformed token-id list is required at the request boundary.
  2. In speculative decoding, the rejection sampler can generate recovered tokens when drafted tokens are rejected.
    # vllm/v1/sample/rejection_sampler.py
    def sample_recovered_tokens(...):
        recovered_token_ids = torch.empty_like(draft_token_ids)
        sample_recovered_tokens_kernel[(batch_size, max_spec_len)](...)
        return recovered_token_ids
    
    On the verified Qwen3 run,…
Record
GHSA-8wr5-jm2h-8r4f
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-20
Updated
2026-11-02
NVD 7.5

vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs. Prior to 0.24.0, a frontend-legal multi-request speculative decoding workload can cause the rejection sampler to produce a recovered token equal to the model vocabulary size boundary value, which is then converted to negative one when the engine selects the next live token for a request and is written back into the drafter's input ids; that out-of-vocabulary value is later consumed by the model's embedding and attention path and crashes the engine worker with a GPU device-side assertion. The same triggering request sequence is reachable through the public gRPC Generate and Abort endpoints, so a remote client that can send generation requests can crash the shared engine worker, aborting concurrent requests and causing a service-wide denial of service for other clients of the deployment until the worker is restarted. This issue is fixed in version 0.24.0.

Record
CVE-2026-54234
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-20, CWE-1284
Updated
2026-11-02
OSV 7.5

vLLM: Remote DoS in vLLM via Invalid Recovered Token Reinjection

vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs. Prior to 0.24.0, a frontend-legal multi-request speculative decoding workload can cause the rejection sampler to produce a recovered token equal to the model vocabulary size boundary value, which is then converted to negative one when the engine selects the next live token for a request and is written back into the drafter's input ids; that out-of-vocabulary value is later consumed by the model's embedding and attention path and crashes the engine worker with a GPU device-side assertion. The same triggering request sequence is reachable through the public gRPC Generate and Abort endpoints, so a remote client that can send generation requests can crash the shared engine worker, aborting concurrent requests and causing a service-wide denial of service for other clients of the deployment until the worker is restarted. This issue is fixed in version 0.24.0.

Record
CVE-2026-54234
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-1284, CWE-20
Updated
2026-11-10
OSVGHSA-8wr5-jm2h-8r4f 7.5

vLLM has Remote DoS via Invalid Recovered Token Reinjection

Summary

A frontend-legal multi-request speculative workload can make vLLM produce an out-of-vocabulary recovered token equal to vocab_size, convert that value to -1 when choosing the next live token for a request, and then feed that -1 back into the next drafter input ids. On Qwen3 GPTQ this reaches the worker-side drafting / attention path and crashes the engine with a GPU device-side assert.

The same issue is reachable through the public gRPC request surface by sending a specific overlapping Generate / Abort sequence.

Impact

  • A remote client that can send public gRPC generation requests can crash the shared vLLM engine worker
  • The triggering request sequence aborts concurrent requests and prevents later requests from completing until the worker is restarted
  • In shared deployments, this is a service-wide denial of service for other clients, not just a failure isolated to the attacking requests
  • The failure is reproducible, so repeated request sequences can sustain the outage

Affected version

  • Confirmed on vLLM 0.17.1
  • Earlier and later versions have not been checked yet in this report

Repro model

  • Official Hugging Face repo:
  • Anyone wants to reproduce the bug with my PoC scripts should download Qwen3-0.6B-GPTQ-Int8 first

Trigger chain

  1. A legal multi-request speculative workload keeps structured-output state, speculative decoding, overlap, and request cancellation active in the same live engine.
  2. During rejection sampling, vLLM produces a recovered token equal to the model vocab_size boundary value.
  3. That recovered token appears in position 0 of the sampled speculative row for a live request. The same row also contains trailing padding entries equal to -1, but those padding entries are not the key fault by themselves.
  4. The next-token preparation step treats the position-0 recovered token as the real next token for that request and converts that out-of-vocabulary value to -1.
  5. The drafter writes that converted -1 back into the live next-step input-id row for the request.
  6. The drafting / embedding / attention path later consumes that live invalid token and the worker crashes on GPU.

Details

Simple example

The important distinction is:

  • trailing -1 values in a speculative row can be ordinary padding
  • the bug appears when the first live token for a request becomes 151936 == vocab_size, and that live token is then converted into -1

In simplified form, the bad transition looks like this:

sampled speculative row:
[151936, -1, -1, -1, ...]

At this point, the trailing -1 values are only padding. The critical problem is that the first position holds 151936, which is out of vocabulary and is being treated as the request's real next token.

Then vLLM prepares the next-token buffer:

next_token_ids:
[-1, ...]

Finally, that converted -1 is written back into the live model input ids:

input_ids_after:
[-1, 0, 0, 0, ...]

The crash happens because the live next token became -1 and was later consumed by the drafting / embedding / attention path, not merely because the speculative row contained padded -1 entries.

Trigger path in code

  1. The workload is frontend-legal. The requests use normal SamplingParams features such as structured outputs, stop, bad_words, min_tokens, and streaming overlap. No malformed token-id list is required at the request boundary.
  2. In speculative decoding, the rejection sampler can generate recovered tokens when drafted tokens are rejected.
    # vllm/v1/sample/rejection_sampler.py
    def sample_recovered_tokens(...):
        recovered_token_ids = torch.empty_like(draft_token_ids)
        sample_recovered_tokens_kernel[(batch_size, max_spec_len)](...)
        return recovered_token_ids
    
    On the verified Qwen3 run,…
Record
GHSA-8wr5-jm2h-8r4f
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-20
Updated
2026-11-02
OSVPYSEC-2026-3542 7.5

vLLM has Remote DoS via Invalid Recovered Token Reinjection

Summary

A frontend-legal multi-request speculative workload can make vLLM produce an out-of-vocabulary recovered token equal to vocab_size, convert that value to -1 when choosing the next live token for a request, and then feed that -1 back into the next drafter input ids. On Qwen3 GPTQ this reaches the worker-side drafting / attention path and crashes the engine with a GPU device-side assert.

The same issue is reachable through the public gRPC request surface by sending a specific overlapping Generate / Abort sequence.

Impact

  • A remote client that can send public gRPC generation requests can crash the shared vLLM engine worker
  • The triggering request sequence aborts concurrent requests and prevents later requests from completing until the worker is restarted
  • In shared deployments, this is a service-wide denial of service for other clients, not just a failure isolated to the attacking requests
  • The failure is reproducible, so repeated request sequences can sustain the outage

Affected version

  • Confirmed on vLLM 0.17.1
  • Earlier and later versions have not been checked yet in this report

Repro model

  • Official Hugging Face repo:
  • Anyone wants to reproduce the bug with my PoC scripts should download Qwen3-0.6B-GPTQ-Int8 first

Trigger chain

  1. A legal multi-request speculative workload keeps structured-output state, speculative decoding, overlap, and request cancellation active in the same live engine.
  2. During rejection sampling, vLLM produces a recovered token equal to the model vocab_size boundary value.
  3. That recovered token appears in position 0 of the sampled speculative row for a live request. The same row also contains trailing padding entries equal to -1, but those padding entries are not the key fault by themselves.
  4. The next-token preparation step treats the position-0 recovered token as the real next token for that request and converts that out-of-vocabulary value to -1.
  5. The drafter writes that converted -1 back into the live next-step input-id row for the request.
  6. The drafting / embedding / attention path later consumes that live invalid token and the worker crashes on GPU.

Details

Simple example

The important distinction is:

  • trailing -1 values in a speculative row can be ordinary padding
  • the bug appears when the first live token for a request becomes 151936 == vocab_size, and that live token is then converted into -1

In simplified form, the bad transition looks like this:

sampled speculative row:
[151936, -1, -1, -1, ...]

At this point, the trailing -1 values are only padding. The critical problem is that the first position holds 151936, which is out of vocabulary and is being treated as the request's real next token.

Then vLLM prepares the next-token buffer:

next_token_ids:
[-1, ...]

Finally, that converted -1 is written back into the live model input ids:

input_ids_after:
[-1, 0, 0, 0, ...]

The crash happens because the live next token became -1 and was later consumed by the drafting / embedding / attention path, not merely because the speculative row contained padded -1 entries.

Trigger path in code

  1. The workload is frontend-legal. The requests use normal SamplingParams features such as structured outputs, stop, bad_words, min_tokens, and streaming overlap. No malformed token-id list is required at the request boundary.
  2. In speculative decoding, the rejection sampler can generate recovered tokens when drafted tokens are rejected.
    # vllm/v1/sample/rejection_sampler.py
    def sample_recovered_tokens(...):
        recovered_token_ids = torch.empty_like(draft_token_ids)
        sample_recovered_tokens_kernel[(batch_size, max_spec_len)](...)
        return recovered_token_ids
    
    On the verified Qwen3 run,…
Record
PYSEC-2026-3542
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
vllm
PyPI
0.17.1 up to 0.24.0
0.24.0
vllm
PyPI
0.17.1 up to 0.24.0, plus listed versions
0.18.00.18.10.19.00.19.10.20.0
Show 6 moreShow less
0.20.10.20.20.21.00.22.00.22.10.23.0
0.24.0

History

History
RecordedChangedSources
factsOSV
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-54234 is a high vulnerability (CVSS 7.5) in Vllm, published July 6, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.62%, the 49th percentile. Fixed in vllm 0.24.0.

References

This page doesn't list everything

Left out here: the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open