If you run SGLang in disaggregated prefill/decode mode, there is a concrete check to do today. Cloudflare published a post-mortem on Oct 26, 2026 for a cross-request KV cache exposure in its GLM-5.3 model on Workers AI. The root cause was a config mismatch that hit an engine bug. The engine bug is fixed upstream, but the config check is still yours to make.
What leaked, and how much
Between August 27 and September 9, 2026, 155 responses to prompts longer than 681,280 tokens contained data from other customers' requests to the same model. Cloudflare says the timing and volume are consistent with ordinary long-context use, not deliberate exploitation. Security researcher Gadi Evron of Knostic reported it on September 8 via HackerOne. Cloudflare reproduced it the next morning and took the model offline within 40 minutes of declaring an incident. It restored the model on September 9. No other Workers AI model was affected.
If you want the model background, I covered the GLM-5.3 release in the GLM-5.3 Terminal Bench post.
Two bugs that had to line up
The misconfiguration. Cloudflare deployed GLM 5.3 with a 1,048,576-token context window. The KV cache pool on its prefill GPUs held only 681,280 tokens. SGLang sizes that pool at startup from whatever GPU memory remains after loading weights. Nothing forces it to match the context length. Cloudflare knew about the mismatch before launch. It assumed the engine would return an error for oversize prompts, and its long-context tests returned successful responses. The gap: it validated HTTP status codes and throughput, not output coherence.
The engine bug. SGLang rejected an over-length prompt by swapping it for a one-token placeholder. In disaggregated mode, the admission queues checked req.finished(), not whether the request was rejected. A rejected request stored its rejection in to_finish, so finished() stayed False. The sequence:
- Decode reserved KV pages for the full prompt length (8 pages in Cloudflare's diagram).
- Prefill admitted the request and ran one token.
- Prefill sent one page of KV to decode and signalled transfer complete.
- Decode attended over all 8 reserved pages. Pages P1 to P7 still held earlier requests' prompts and partial generations.
- The client got HTTP 200, not 400, with a coherent reply that arrived faster than an 8-page prefill should.
The post notes pages are not zeroed between requests. The engine is responsible for tracking page ownership.
What to run
Cloudflare recommends v0.5.22 or later. These are the key PRs:
| PR | Release | Effect |
|---|---|---|
| #36988 | v0.5.20 | Retires aborted prefill requests before their result reaches decode |
| #38935 | v0.5.21 | Rejects over-length requests at admission, before bootstrap, allocation or KV transfer |
| #41023 | v0.5.21 | Turns deferred KV release on by default |
| #32758 | v0.5.20 | Optional cap on Mooncake transfer batch size |
| #39500 | v0.5.21 | Adds --disaggregation-enable-kv-checksum |
| #43719 | v0.5.22 | A failed Mooncake send no longer reports its writes as drained |
The post lists further race-condition fixes in v0.5.21 and v0.5.22 if you want to backport rather than upgrade.
The checklist for your own deployment
This is Cloudflare's operator advice, condensed:
- Compare KV pool size to context length on every prefill and decode node. SGLang prints the pool size at startup and exposes it as a metric. Re-check after any change to weights, quantization, parallelism or memory fraction. If the pool is smaller, lower the context length.
- Upgrade to v0.5.22 or later as the backstop for when that check is wrong.
- Run deferred KV release on both roles and bound Mooncake transfer batches.
- Turn on
--disaggregation-enable-kv-checksumand--kv-canary, then confirm in logs that requests are actually being verified. Neither covers every model architecture yet. Cloudflare is working to extend them to GLM 5.3, GLM 5.3 Flash and DeepSeek V4. - Stop your proxy generating needless aborts. Cloudflare changed its load balancer so a client disconnect no longer aborts mid-transfer. It holds the prefill connection until prefill finishes and the decode connection until the first token.
Cloudflare's own fix was to match its GLM 5.2 config, which gives a prefill pool of about 2.04 million tokens, roughly twice the context length. Its deployment checks now require the pool-versus-context comparison, deferred release on both roles, transfer batch bounds and required patches.
What I take from it
The lesson I would apply first is the test gap. A 200 status and a streaming body proved nothing here. If you serve long contexts, add a canary-marker test: send distinct marked prompts concurrently, then send over-length prompts and check that no marker appears in any response. Cloudflare validated its fix this way, using canary-marker tests plus the researcher's reproduction script.
The catch is that the checksum and canary checks are partial. Cloudflare says page-level tags, which check every decode read, are the durable answer. Its prototype cost under 1% in throughput and tail latency, but it was disabled after reliability issues and is tied to specific attention backends. Zeroing KV pages on release is only a draft proposal (#46435). Until those land, the pool check and the upgrade are what you have.
Sources:
- Cloudflare, "Cross-request KV cache exposure in the GLM-5.3 Workers AI model, and our remediation with SGLang": https://blog.cloudflare.com/kv-cache-exposure-remediation
- Earlier coverage on this site: https://www.neoteric.no/blog/glm-5-3-open-weight-terminal-bench