Como a Cloudflare encontrou um bug na hyper HTTP library
Aprofundamento CEVIU
Aprofundamento
A Cloudflare identificou um bug de condição de corrida na biblioteca hyper, usada para gerenciar conexões HTTP em Rust, que truncava respostas de imagens grandes sem retornar erro. O problema só aparecia quando o buffer do socket de Unix entre o serviço Images e o intermediário interno enchia, algo que não ocorria antes da troca do FL por Unix sockets em dezembro de 2025. O FL, por ser mais lento e ter overhead de rede, consumia os dados antes que o buffer enchesse. O novo intermediário, mais rápido, criou um ponto de estrangulamento sutil: o hyper descartava o resultado do flush sem verificar se ainda havia dados pendentes, encerrando a conexão prematuramente.
A correção foi mínima: quatro linhas de código que passaram a verificar o retorno de poll_flush antes de prosseguir. Em vez de usar let _ = poll_flush(), o código agora espera o Poll::Pending e continua o loop até que todo o buffer seja esvaziado. Isso não é apenas um ajuste de biblioteca, é um lembrete de que otimizações de desempenho podem expor falhas de tempo em camadas invisíveis, especialmente em sistemas distribuídos onde cada milissegundo conta.
Por que isso importa
Esse bug afeta diretamente a confiabilidade de serviços que dependem de streaming de dados grandes via HTTP/1, como APIs de processamento de imagem, vídeo ou arquivos binários. A ausência de erros visíveis, status 200 com corpo truncado, torna a detecção difícil e a falha silenciosa. Para equipes de DevOps e SREs, isso reforça a necessidade de observabilidade em nível de kernel, não só de aplicação. Monitorar syscalls como write e shutdown com ferramentas como strace pode revelar falhas que logs e traces distribuídos não capturam. É um caso clássico de como melhorias de latência podem introduzir novos tipos de falha, e como a engenharia de confiabilidade exige entender o sistema inteiro, da aplicação até o kernel.
Linha do tempo
Cloudflare substitui o intermediário FL por Unix sockets para acelerar a conexão entre Workers e o serviço Images
Primeiros relatos de imagens truncadas no binding Images, com resposta 200 OK e corpo incompleto
Cloudflare publica detalhes da correção de quatro linhas no hyper, após seis semanas de investigação com strace
Perguntas frequentes
Por que o bug só apareceu depois da mudança para Unix sockets?
O intermediário antigo, FL, era mais lento e consumia os dados do socket gradualmente, evitando que o buffer enchesse. O novo intermediário, mais eficiente, lê os dados mais rápido, mas não tão rápido quanto o hyper escreve em blocos grandes. Isso criou uma janela de backpressure onde o buffer do socket enchia, e o hyper, por descartar o resultado do flush, encerrava a conexão antes de enviar tudo.
Por que o erro não foi detectado nos testes locais?
Testes locais não replicavam a carga real e a concorrência da produção. O bug dependia de timing preciso entre a escrita do hyper e a leitura do cliente, algo que só ocorria com múltiplas requisições simultâneas no ambiente de edge. Em máquinas locais, o sistema operacional e o carregamento da rede eram diferentes, mascarando o problema.
Como o uso de let _ = poll_flush() causou o problema?
Em Rust, let _ descarta o valor retornado por uma função. Quando poll_flush retornava Poll::Pending, indicando que o buffer do socket ainda estava cheio, o código ignorava esse sinal e prosseguia para encerrar a conexão. Isso fez com que o hyper acreditasse que havia terminado de enviar os dados, mesmo quando ainda havia megabytes pendentes no buffer interno.
Por que a atualização da versão do hyper não resolveu?
O bug estava presente em todas as versões da hyper, desde a 0.14 até a 1.8. Não era um erro corrigido em uma versão posterior, mas sim um comportamento intencional na lógica do loop de dispatch, uma decisão de design que funcionava na maioria dos casos, mas falhava em cenários de backpressure extremo. A correção exigiu mudar o código que usava a biblioteca, não atualizá-la.
Fontes
- blog.cloudflare.comfonte original
- Categoria
- CEVIU DevOps
- Publicado
- 24 de junho de 2026
- Editoria
- CEVIU DevOps

