veilletech.fr
27 oct. Feed du jour
#04 IA Article

Workers AI : le cache KV fuit d'un client à l'autre

Un statut 200 ne prouve pas que la réponse est la vôtre.

Du 27 août au 9 septembre, 155 réponses de GLM 5.3 sur Workers AI ont contenu des données d'autres clients : le cache KV de prefill était plus petit que le contexte annoncé, et SGLang acceptait au lieu de rejeter les prompts trop longs. Cloudflare a corrigé sa configuration et publié avec SGLang un correctif, disponible en 0.5.22. Le contrôle à faire chez soi : pool KV contre longueur de contexte.

4 min de lectureavancévidéo 1:13
Partager
Sommaire6 sections
  1. Ce qui s'est passé
  2. Deux défauts qui s'additionnent
  3. Chronologie (UTC)
  4. Ce que Cloudflare a changé
  5. Comment s'y prendre
  6. À retenir

Ce qui s'est passé

Entre le 27 août et le 9 septembre 2026, des clients de Workers AI qui interrogeaient le modèle @cf/zai-org/glm-5.3 ont reçu des réponses contenant des données d'autres clients, venues de requêtes faites juste avant les leurs. Cloudflare compte 155 réponses touchées, toutes pour des prompts de plus de 681 280 tokens. Aucun autre modèle de la plateforme n'était concerné.

Les requêtes concernées correspondent, par leur rythme et leur volume, à un usage normal en contexte long, pas à quelqu'un qui exploiterait la faille. Cloudflare dit n'avoir trouvé aucune preuve d'exploitation délibérée.

Deux défauts qui s'additionnent

1. Une configuration. GLM 5.3 était déployé avec un contexte de 1 048 576 tokens, mais le pool du cache KV des GPU de prefill, dimensionné au démarrage par SGLang avec la mémoire restante après le chargement des poids, n'atteignait que 681 280 tokens. Cloudflare connaissait cet écart. L'équipe comptait sur une erreur du moteur pour tout prompt trop long, et ses tests de contexte long renvoyaient des réponses réussies : elle ne vérifiait que les codes HTTP et les performances, pas le contenu des sorties.

2. Un bug de SGLang en mode désagrégé (prefill et décodage sur des GPU distincts, le cache passant de l'un à l'autre par RDMA via Mooncake). Un prompt trop long était marqué rejeté et remplacé par un jeton factice, mais les files d'admission vérifiaient si la requête était terminée, pas rejetée : elle passait donc pour vivante.

PrefillDécodageRouteurClientPrefillDécodageRouteurClientPrompt très long1Réserver N pages2Même prompt31 page, transfert terminé4Réponse 2005
Un prompt trop long : le rejet est ignoré et le décodage lit des pages qui ne sont pas les siennes

Le décodage avait réservé les pages pour tout le prompt ; une seule avait été écrite par cette requête. Il générait en lisant aussi les autres, qui contenaient encore les prompts et les générations partielles de clients précédents. Côté client : un statut 200 au lieu d'un 400, un nombre de tokens de prompt exact, une réponse cohérente, et plus rapide que ne le permettait un vrai prefill.

Les pages du cache ne sont pas remises à zéro entre deux requêtes : c'est courant dans les moteurs d'inférence et nécessaire aux meilleures performances, mais cela laisse au moteur seul la charge de savoir à qui appartient chaque page.

Chronologie (UTC)

Ce que Cloudflare a changé

Le bug avait été signalé à SGLang le 6 juillet (issue #30233). Le correctif est sorti en v0.5.20, complété en v0.5.21 (2 octobre) et v0.5.22 (19 octobre).

Comment s'y prendre

  1. Si vous exploitez SGLang en désagrégé, passez en 0.5.22 ou plus.
  2. Au démarrage, lisez la taille du pool KV choisie (affichée dans les journaux, exposée en métrique) et comparez-la au contexte annoncé.
  3. Testez les prompts longs en vérifiant le contenu des réponses, pas seulement le statut HTTP et la latence.

Source : Cloudflare, 26 octobre 2026. Source en anglais.