On 26 October, Cloudflare published a security report about its own inference platform. The company was unusually direct about what went wrong, and unusually direct about why nobody noticed.

Between 27 August and 9 September 2026, a small number of customers using one model on Workers AI — GLM-5.3, from Z.ai — received responses that contained data from other customers' requests made to the same model shortly beforehand. Cloudflare's report puts the number at 155 affected responses, all to prompts longer than 681,280 tokens.

Those customers were not told by an error message. They received HTTP 200. They received a reply that was coherent, whose reported prompt_tokens matched the long prompt they had sent. The only sign anything was wrong was that the answer arrived faster than a prompt of that length should take, and that parts of it belonged to somebody else.

Two faults that had to line up

Cloudflare's account describes two independent problems that overlapped.

The first was a configuration mismatch the company says it knew about before launch. GLM-5.3 was deployed with a context window of 1,048,576 tokens. The key-value cache pool on the prefill GPUs — the memory that holds a prompt's internal representation while the model processes it — had room for only 681,280 tokens.

That number is not a round fraction of the context window, and Cloudflare's report explains why the two figures need not agree: the pool “is not a configuration value. SGLang sizes it at startup from whatever GPU memory remains after loading the model weights. The model's advertised context length is a separate configuration value. Nothing forces the two to agree, and it is our job to check that they do.”

They checked. They found the mismatch. They shipped anyway, on the expectation that the engine would reject a prompt it could not hold — a reasonable expectation, and a wrong one.

The second fault was in SGLang, the open-source inference engine Cloudflare uses. When a prompt exceeded the pool, the scheduler correctly flagged it for rejection, recorded the error for the client, and swapped in a one-token placeholder so the request could drain through the normal batch machinery. On a single machine, this worked: the placeholder ran, the batch finished, the client got an error.

Cloudflare runs SGLang in a disaggregated configuration — one pool of GPUs processes the prompt and writes the key-value cache, then hands that cache over RDMA to a second pool that generates the reply. In that arrangement, the admission queues on both sides checked whether a request was finished, not whether it was rejected. A rejected request reported itself as live.

So the handoff proceeded. In the report's worked example, the decode node reserved eight pages of cache for a request that had only ever written one — and generated from all eight. Pages two through eight still held whatever earlier requests had left in them — other users' prompts and partial generations, since the pages are reused without being zeroed between requests.

The client received a successful response assembled partly from other people's data.

The part that should worry you

The engineering failure is instructive. The detection failure is the story.

Cloudflare states plainly that it validated the wrong things: “we only validated HTTP response codes and engine performance at long contexts, without validating model output and coherence.”

Every check Cloudflare describes returned success. The status code was 200. The stream had no error frames. The latency looked fine — faster than an eight-page prefill should take, which was itself the only anomaly, not a reassurance. The system was wrong, and every instrument pointed at green.

There is a specific reason this is worth dwelling on. The bug only triggered above 681,280 tokens — beyond the working memory most users will ever touch, in the range that long-context agentic workloads occupy. The population exposed was small. Cloudflare does not say who those customers were or what they were working on. What it says is this: “After excluding our own testing and the researcher's, the requests we identified are consistent in timing and volume with ordinary long-context use, not with someone repeatedly exploiting the bug.” That is a statement about the requests Cloudflare identified after that exclusion, not about all 155.

A known bug, seven and a half weeks earlier

The most uncomfortable detail in Cloudflare's report is not in its incident timeline.

The underlying SGLang defect “had been reported to SGLang by another user as issue #30233” on 6 July 2026 — seven and a half weeks before GLM-5.3 went live with the flaw present, and roughly nine weeks before anyone at Cloudflare learned of it.

An open bug, in a public tracker, in an inference engine that a major platform was about to put into production. The report does not say whether anyone at Cloudflare saw the issue before the incident; it says only that Cloudflare noticed it “while investigating this incident.” Cloudflare notes it had “been flagging these types of issues with SGLang since v0.5.10” — a reference to the class of KV-cache memory-safety bugs, not to this particular issue. The same sentence credits work already under way with the SGLang team, and the report adds that the fix stopping this exposure was already merged to SGLang main as #36988 on 6 September, before this report reached Cloudflare, but had not been released.

This is the least glamorous and most transferable finding in the whole report. It is not a story about a clever attacker. It is a story about an ordinary failure of the kind that software has always had, arriving in a new place: AI inference is now infrastructure, and it carries infrastructure's supply-chain problems.

What was fixed

Cloudflare took the model offline within 40 minutes of declaring an incident, and restored it on 9 September.

Two changes: the pool now holds about 2.04 million tokens, roughly twice the context window, so a valid request always fits; and the engine's rejection path was patched so a request carrying a pending rejection is retired at the admission queue rather than handed onward. The fix and its follow-ups landed upstream in SGLang v0.5.20, v0.5.21 and v0.5.22.

Cloudflare says GLM-5.3 was the only model affected, because every other disaggregated deployment on Workers AI has pools larger than its context length on both sides, so no request could reach the rejection path. It says it found no evidence of deliberate exploitation: after excluding its own testing and the researcher's, the affected requests were consistent in timing and volume with ordinary long-context use.

The flaw was reported to Cloudflare by Gadi Evron of Knostic through its HackerOne programme, with a reproduction script. Cloudflare credits that script as the reason it could fix and validate the change before restoring the model.

The defence that was switched off

Cloudflare's report is explicit about the limits of what it has done.

The durable fix, in the company's framing, is “integrity by construction”: tag every physical cache page, have each request record the tags it expects, and verify the mapping before the decoder reads — failing one request rather than returning someone else's data. Cloudflare built a prototype. Its own tests put the cost “under 1% in throughput and tail latency.”

It tested that prototype on GLM-5.2 in mid-August. Then it disabled it shortly afterwards due to reliability issues, and because it was tied to specific attention backends and model architectures, it “could not be a general fix.”

That is a notable admission: the structural solution existed, measured cheap in Cloudflare's own tests, and was switched off before it was reliable or general. The report does not claim the prototype would have prevented this incident. The protections that shipped are configuration checks and lifecycle fixes, which Cloudflare itself concedes “reduce the number of ways a page can be misused. They do not make misuse impossible, and this incident is a reminder that the next bug will have a shape we have not seen.”

The company says it is now directing formal-verification work at RDMA key-value cache transfer, aiming to prove the protocol's safety properties. It expects gaps.

What we are not told

Cloudflare does not publish the number of distinct customers whose data appeared in someone else's response, the number who received it, or the maximum amount of another user's content contained in a single reply. It does not say whether affected customers were individually notified, or how someone receiving one of these responses could have known it was not theirs to read. It has not published the researcher's reproduction script.

Its conclusion that there was no deliberate exploitation is a finding from its own analysis, and should be read as such.

What this means if you use hosted inference

Cloudflare's own recommendations to other operators are the most useful part of the report, and they are not reassuring: measure your cache pool against your context length on every prefill and decode node, from the engine's startup log, after every change to weights, quantization, parallelism or memory fraction — and if the pool is smaller, lower the context length to fit. And do not assume the engine will reject what does not fit. As the report puts it: “Do not rely on a proxy to enforce the limit”.

Anyone running multi-tenant inference on shared KV cache is relying on the engine to track page ownership correctly. That ownership tracking is not currently guaranteed by the model's advertised capabilities, and the corruption detection flags SGLang provides “do not yet cover every model architecture.”

The exposure window here was thirteen days, discovered by an outside researcher who happened to be looking.