Technology reviews & practical guides
Cloudflare's post-mortem says a KV cache sizing mistake and an SGLang prefill/decode bug let 155 long-prompt GLM-5.3 responses carry other customers' data between Aug 27 and Sep 9, 2026. The fix is upstream in SGLang.

On October 26, Cloudflare published a post-mortem of a cross-tenant data exposure in Workers AI, its hosted AI inference service. Between August 27 and September 9, 2026, some responses from the GLM-5.3 model contained data from other customers' requests made to the same model shortly before. Cloudflare counts 155 affected responses, all to prompts longer than 681,280 tokens, and says it found no evidence of deliberate exploitation.
The cause was not a jailbreak or a flaw in the model itself. It sat in the serving stack: a GPU memory pool smaller than the advertised context window, combined with a bug in SGLang, the open-source inference engine behind the deployment. The fix has shipped upstream, which makes the disclosure relevant to anyone who self-hosts large language models with SGLang, not only to Cloudflare customers.
The post, titled "Cross-request KV cache exposure in the GLM-5.3 Workers AI model, and our remediation with SGLang" and written by Michelle Chen, was published as a coordinated disclosure alongside a companion post from the SGLang team, "SGLang security update: improving request isolation".
The problem was reported by Gadi Evron. In Cloudflare's words, he "submitted a report on September 8 through our HackerOne program stating that very long prompts sent to @cf/zai-org/glm-5.3 on Workers AI sometimes returned text that belonged to other users' sessions." The report included a reproduction script.
The "KV cache" in this incident is the transformer key/value attention cache that an inference engine keeps in GPU memory while it processes a prompt. It has nothing to do with Workers KV, Cloudflare's key-value storage product.
Workers AI serves GLM-5.3 with prefill/decode disaggregation. Prefill GPUs read the prompt and build its KV cache, then send that cache over RDMA, using the Mooncake transfer engine, to separate decode GPUs that generate the answer.
The first mistake was in the configuration. Cloudflare writes: "We deployed GLM 5.3 with a 1,048,576-token context window, but the KV cache pool on our prefill GPUs only had room for 681,280 tokens." The team knew about the mismatch before launch and expected the engine to return an error for prompts that were too long.
The second was an engine bug that broke that assumption. SGLang marked an over-length request as rejected and swapped its prompt for a one-token placeholder. But both disaggregation admission queues checked req.finished() instead of checking whether the request had been rejected, so the request went through the prefill-to-decode handoff anyway.
Decode then reserved KV pages for the full-length prompt, but only the first page was actually written. The remaining pages still held whatever the previous occupants had left there - other users' prompts and partial generations - and the model attended over them. The client received HTTP 200 and a coherent answer containing other users' content, instead of the HTTP 400 error it should have got.

Only GLM-5.3 hit this path. Cloudflare explains: "Every other disaggregated deployment on Workers AI has KV pools larger than its context length on both prefill and decode, so no request could reach the rejection path."
Cloudflare's timeline, in UTC:
The exposure itself ended on September 9. The disclosure came about seven weeks later, once the upstream fixes were available in released SGLang versions.
SGLang's companion post describes a second isolation problem in the same part of the engine. When a request is aborted, decode can free its KV slots while RDMA writes that are already in flight keep landing. If those slots have been reassigned to another request in the meantime, the stale writes end up inside that other request's KV cache.

The window grows with prompt length: for 128K to 1M-token contexts it lasts seconds to minutes. The underlying constraint is that a DMA transfer, once launched, cannot be cancelled, so the only safe reaction to an abort is to wait for it to finish.

SGLang's fixes for this race:
On the configuration side, Cloudflare writes: "We adjusted our GLM 5.3 configuration to match our GLM 5.2 configuration, which freed enough GPU memory that the prefill KV pool now holds about 2.04 million tokens, roughly twice the 1,048,576-token context length."
In the engine, a request with a pending rejection is now retired at the disaggregation admission queue with its original error, before any bootstrap, KV allocation or KV transfer. The related upstream pull requests are #38704 (Cloudflare's draft patch), #36988 (merged on September 6 for a related failure path, shipped in v0.5.20) and #38935 (rejects these requests earlier, shipped in v0.5.21).
Further hardening on Workers AI includes:
Cloudflare also prototyped integrity tagging of KV data, which cost under 1% in throughput and tail latency.
According to SGLang, the affected setups are prefill-decode (PD) disaggregated deployments with a KV cache transfer backend: Mooncake, NIXL, MORI or a custom one. Default PD configurations from the v0.4.x line through v0.5.21 are affected, and through v0.5.22 for MORI. Single-instance deployments without cross-engine transfer are not affected. Neither post gives a CVE or advisory ID.
For operators stuck on v0.5.19 or v0.5.20, SGLang lists a stopgap: set the first variable below on both prefill and decode, and on v0.5.20 also set the transfer batch limit and raise the release timeout to 60 to 120 seconds. SGLang is clear that these settings do not replace upgrading.
SGLANG_DISAGGREGATION_DEFERRED_DECODE_KV_RELEASE=1
# v0.5.20 only, in addition:
SGLANG_MOONCAKE_MAX_TRANSFER_BATCH_INDICES=<limit>
SGLANG_DISAGGREGATION_DEFERRED_DECODE_KV_RELEASE_TIMEOUT=<60-120>
SGLang also added optional Adler-32 verification of transferred KV cache (#39500), enabled with --disaggregation-enable-kv-checksum on both prefill and decode. It is off by default because it adds GPU reads and a sync point, so upgrading alone does not turn it on.
Hosted inference packs many customers onto the same GPUs, and reusing KV cache memory between requests is part of what makes that efficient. This incident shows that the isolation boundary between those customers can run through memory pages managed by the inference engine - something no amount of model safety training controls.
It also shows how a known limit can turn into a leak. Cloudflare knew its prefill pool was smaller than the advertised context window and relied on an error path that, because of a one-line check, never fired. Its new pre-deployment check, which compares KV pool size with context length, targets exactly that gap.
Cloudflare's post does not say whether affected customers were notified individually.
More in Tech News
Browse Tech News