El incidente fue causado por una race condition latente en la librería hyper (HTTP/1 dispatch loop) que se manifestó debido a un cambio arquitectónico en Cloudflare. La re-arquitectura del Images binding, que pasó de usar un intermediario FL con sockets de red a un nuevo intermediario con Unix sockets en la misma máquina, hizo que el lector de la conexión (el nuevo intermediario) introdujera pausas milisegundos en el consumo de datos. Estas pausas permitieron que el buffer del socket se llenara ocasionalmente, exponiendo el fallo.

El problema residía en cómo hyper manejaba el flushing de datos y el cierre de la conexión. Cuando el Images service terminaba de codificar una imagen y entregaba el bloque completo a hyper, este lo escribía en su buffer interno y marcaba la operación de escritura como completa. Luego, llamaba a poll_flush para mover los datos al socket. Si el socket estaba lleno, poll_flush devolvía Poll::Pending, indicando que no había terminado. Sin embargo, el poll_loop de hyper descartaba este resultado (let _ = self.poll_flush(cx)?), lo que significaba que el loop no sabía que el flush estaba incompleto. Consecuentemente, el loop procedía a cerrar la conexión (poll_shutdown) mientras aún quedaban datos en el buffer interno de hyper.

Las salvaguardas a nivel de aplicación fallaron porque el sistema creía que todo estaba bien. Los logs no mostraban errores, el servicio retornaba 200 OK, y el tracing distribuido indicaba que la respuesta había sido enviada. La truncación ocurría a un nivel más bajo, en la interacción entre hyper y el kernel, lo que la hacía invisible para las herramientas de observabilidad de alto nivel. La naturaleza intermitente y la dependencia del tamaño de la imagen y la concurrencia dificultaron la reproducción y el diagnóstico, ya que herramientas como curl o la observación directa con strace (sin un filtrado cuidadoso) alteraban las condiciones de la race condition.