Every CVE Search/ Get API key

CVE-2026-115914

vLLM DeepSeek-OCR image processing vulnerable to denial of service

6.5 MediumFix available

vLLM is an inference and serving engine for large language models. From 0.11.1 until 0.32.0, the DeepSeek-OCR, DeepSeek-OCR-2, and Unlimited-OCR image path allows a remote client that can reach the OpenAI-compatible API to submit a legal image whose normalized pixels sum to zero when that image is alone in its per-step encoder batch. _parse_and_validate_image_input returns no embedding, embed_multimodal propagates that value, and sanity_check_mm_encoder_outputs triggers a fatal assertion that shuts down the engine for all users. This issue is fixed in version 0.32.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.40%Unchanged since Oct 27, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.5

vLLM DeepSeek-OCR image processing vulnerable to denial of service

vLLM is an inference and serving engine for large language models. From 0.11.1 until 0.32.0, the DeepSeek-OCR, DeepSeek-OCR-2, and Unlimited-OCR image path allows a remote client that can reach the OpenAI-compatible API to submit a legal image whose normalized pixels sum to zero when that image is alone in its per-step encoder batch. _parse_and_validate_image_input returns no embedding, embed_multimodal propagates that value, and sanity_check_mm_encoder_outputs triggers a fatal assertion that shuts down the engine for all users. This issue is fixed in version 0.32.0.

Record
CVE-2026-115914
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-617
Updated
2026-11-02
EUVDEUVD-2026-110032 6.5

vLLM is an inference and serving engine for large language models. From 0.11.1 until 0.32.0, the DeepSeek-OCR, DeepSeek-OCR-2, and Unlimited-OCR image path allows a remote client that can reach the OpenAI-compatible API to submit a legal image whose normalized pixels sum to zero when that image is alone in its per-step encoder batch. _parse_and_validate_image_input returns no embedding, embed_multimodal propagates that value, and sanity_check_mm_encoder_outputs triggers a fatal assertion that shuts down the engine for all users. This issue is fixed in version 0.32.0.

Record
EUVD-2026-110032
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-gq5q-89c7-vhvx 6.5

vLLM DeepSeek-OCR image processing vulnerable to denial of service

Summary

Any vLLM deployment serving a model of the DeepSeek-OCR family — deepseek-ai/DeepSeek-OCR, deepseek-ai/DeepSeek-OCR-2, or baidu/Unlimited-OCR (whose UnlimitedOCRForCausalLM subclasses DeepseekOCRForCausalLM) — can be killed by a single unauthenticated chat request carrying an ordinary, schema-valid PNG image, under completely default server configuration.

The image model's input validation contains a guard inherited from the upstream DeepSeek-OCR reference implementation:

# vllm/model_executor/models/deepseek_ocr.py:478-479  (_parse_and_validate_image_input)
if torch.sum(pixel_values).item() == 0:
    return None

In the original research code this was an empty-batch shortcut; in vLLM's serving architecture pixel_values is the actual client image tensor, and the condition is exactly satisfiable by a legitimate image: the in-tree DeepseekOCRProcessor normalizes pixels with ToTensor + Normalize(0.5, 0.5) (vllm/transformers_utils/processors/deepseek_ocr.py:120-140), mapping pixel value 0 → exactly −1.0 and 255 → exactly +1.0 in float32. A 1024×1024 image that is half pure black and half pure white (a perfectly ordinary 1-bit-style scanned-document PNG for an OCR model) therefore yields torch.sum(pixel_values) == 0.0 exactly (equal counts of ±1.0; pairwise reduction stays integer-exact, well inside float32's 2²⁴ exactness bound). ImageOps.pad(image, (1024, 1024)) is the identity map for an already-1024×1024 image (processors/deepseek_ocr.py:350-355), so no padding pixels disturb the balance.

Returning None makes embed_multimodal return None (deepseek_ocr.py:606-611), which immediately trips the engine-side sanity check in the worker:

# vllm/v1/worker/utils.py:512  (sanity_check_mm_encoder_outputs)
assert isinstance(mm_embeddings, (list, tuple, torch.Tensor)), (
    "Expected multimodal embeddings to be a list/tuple of 2D tensors, ...")

The AssertionError is raised inside the encoder runner of the EngineCore worker process with no per-request containment, escapes to the busy loop's top-level handler (vllm/v1/engine/core.py:1368, "EngineCore encountered a fatal error."), triggers EngineDeadError at the API server (vllm/v1/engine/async_llm.py:843), and the whole process tree shuts down permanently. /health refuses connections until a manual restart.

Verified end-to-end on the official vllm/vllm-openai:v0.30.0 image (id d076d77d8dad) with real deepseek-ai/DeepSeek-OCR weights: after confirming /health 200, a text chat 200, and two control images (all-white and all-black 1024×1024) 200, the single half-black/half-white request returned HTTP 500 (EngineCore encountered an issue), the engine log shows AssertionError: Expected multimodal embeddings to be a list/tuple of 2D tensors ... got <class 'NoneType'> at v1/worker/utils.py:512, the API server shut itself down, and the container exited (Exited (0), OOMKilled=false). Every subsequent request, including GET /health, fails at the socket. The vulnerable check is unchanged on main (verified 2026-09-30 against the raw file on the default branch).

Environment notes (disclosed for completeness; unrelated to the sink): (1) the v0.30.0 image's Triton version refuses to compile deepencoder.py's fused rel-pos attention kernel (LOG2E non-constexpr global) during the startup profile run; per the compiler's own suggestion we set TRITON_ALLOW_NON_CONSTEXPR_GLOBALS=1 — an environment workaround only, no source file was modified. (2) DeepSeek-OCR ships no chat_template, so verification passed a one-line --chat-template that concatenates message content text; this does not touch the image data path. (3) The zero-sum check aggregates over the whole per-step modality batch, so the trigger image must be alone in its encoder batch — trivially true on an idle instance (our verification: first attempt, single request), and simply retried otherwise.

##…

Record
GHSA-gq5q-89c7-vhvx
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-617
Updated
2026-11-02
NVD 6.5

vLLM is an inference and serving engine for large language models. From 0.11.1 until 0.32.0, the DeepSeek-OCR, DeepSeek-OCR-2, and Unlimited-OCR image path allows a remote client that can reach the OpenAI-compatible API to submit a legal image whose normalized pixels sum to zero when that image is alone in its per-step encoder batch. _parse_and_validate_image_input returns no embedding, embed_multimodal propagates that value, and sanity_check_mm_encoder_outputs triggers a fatal assertion that shuts down the engine for all users. This issue is fixed in version 0.32.0.

Record
CVE-2026-115914
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-617
Updated
2026-11-02
OSV 6.5

vLLM DeepSeek-OCR image processing vulnerable to denial of service

vLLM is an inference and serving engine for large language models. From 0.11.1 until 0.32.0, the DeepSeek-OCR, DeepSeek-OCR-2, and Unlimited-OCR image path allows a remote client that can reach the OpenAI-compatible API to submit a legal image whose normalized pixels sum to zero when that image is alone in its per-step encoder batch. _parse_and_validate_image_input returns no embedding, embed_multimodal propagates that value, and sanity_check_mm_encoder_outputs triggers a fatal assertion that shuts down the engine for all users. This issue is fixed in version 0.32.0.

Record
CVE-2026-115914
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-617
Updated
2026-11-02
OSVGHSA-gq5q-89c7-vhvx 6.5

vLLM DeepSeek-OCR image processing vulnerable to denial of service

Summary

Any vLLM deployment serving a model of the DeepSeek-OCR family — deepseek-ai/DeepSeek-OCR, deepseek-ai/DeepSeek-OCR-2, or baidu/Unlimited-OCR (whose UnlimitedOCRForCausalLM subclasses DeepseekOCRForCausalLM) — can be killed by a single unauthenticated chat request carrying an ordinary, schema-valid PNG image, under completely default server configuration.

The image model's input validation contains a guard inherited from the upstream DeepSeek-OCR reference implementation:

# vllm/model_executor/models/deepseek_ocr.py:478-479  (_parse_and_validate_image_input)
if torch.sum(pixel_values).item() == 0:
    return None

In the original research code this was an empty-batch shortcut; in vLLM's serving architecture pixel_values is the actual client image tensor, and the condition is exactly satisfiable by a legitimate image: the in-tree DeepseekOCRProcessor normalizes pixels with ToTensor + Normalize(0.5, 0.5) (vllm/transformers_utils/processors/deepseek_ocr.py:120-140), mapping pixel value 0 → exactly −1.0 and 255 → exactly +1.0 in float32. A 1024×1024 image that is half pure black and half pure white (a perfectly ordinary 1-bit-style scanned-document PNG for an OCR model) therefore yields torch.sum(pixel_values) == 0.0 exactly (equal counts of ±1.0; pairwise reduction stays integer-exact, well inside float32's 2²⁴ exactness bound). ImageOps.pad(image, (1024, 1024)) is the identity map for an already-1024×1024 image (processors/deepseek_ocr.py:350-355), so no padding pixels disturb the balance.

Returning None makes embed_multimodal return None (deepseek_ocr.py:606-611), which immediately trips the engine-side sanity check in the worker:

# vllm/v1/worker/utils.py:512  (sanity_check_mm_encoder_outputs)
assert isinstance(mm_embeddings, (list, tuple, torch.Tensor)), (
    "Expected multimodal embeddings to be a list/tuple of 2D tensors, ...")

The AssertionError is raised inside the encoder runner of the EngineCore worker process with no per-request containment, escapes to the busy loop's top-level handler (vllm/v1/engine/core.py:1368, "EngineCore encountered a fatal error."), triggers EngineDeadError at the API server (vllm/v1/engine/async_llm.py:843), and the whole process tree shuts down permanently. /health refuses connections until a manual restart.

Verified end-to-end on the official vllm/vllm-openai:v0.30.0 image (id d076d77d8dad) with real deepseek-ai/DeepSeek-OCR weights: after confirming /health 200, a text chat 200, and two control images (all-white and all-black 1024×1024) 200, the single half-black/half-white request returned HTTP 500 (EngineCore encountered an issue), the engine log shows AssertionError: Expected multimodal embeddings to be a list/tuple of 2D tensors ... got <class 'NoneType'> at v1/worker/utils.py:512, the API server shut itself down, and the container exited (Exited (0), OOMKilled=false). Every subsequent request, including GET /health, fails at the socket. The vulnerable check is unchanged on main (verified 2026-09-30 against the raw file on the default branch).

Environment notes (disclosed for completeness; unrelated to the sink): (1) the v0.30.0 image's Triton version refuses to compile deepencoder.py's fused rel-pos attention kernel (LOG2E non-constexpr global) during the startup profile run; per the compiler's own suggestion we set TRITON_ALLOW_NON_CONSTEXPR_GLOBALS=1 — an environment workaround only, no source file was modified. (2) DeepSeek-OCR ships no chat_template, so verification passed a one-line --chat-template that concatenates message content text; this does not touch the image data path. (3) The zero-sum check aggregates over the whole per-step modality batch, so the trigger image must be alone in its encoder batch — trivially true on an idle instance (our verification: first attempt, single request), and simply retried otherwise.

##…

Record
GHSA-gq5q-89c7-vhvx
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-617
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
vllm
PyPI
0.11.1 up to 0.32.0
0.32.0
vllm
PyPI
0.11.1 up to 0.32.0, plus listed versions
0.11.20.12.00.13.00.14.00.14.1
Show 26 moreShow less
0.15.00.15.10.16.00.17.00.17.10.18.00.18.10.19.00.19.10.20.00.20.10.20.20.21.00.22.00.22.10.23.00.24.00.25.00.25.10.26.00.27.00.27.10.28.00.29.00.30.00.31.0
0.32.0

History

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

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

In short

CVE-2026-115914 is a medium vulnerability (CVSS 6.5) in Vllm, published October 26, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.40%, the 34th percentile. Fixed in vllm 0.32.0.

References

This page doesn't list everything

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

MoveEnter Open