BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Cloudflare Identifies Race Condition in hyper’s HTTP/1 Implementation

Cloudflare Identifies Race Condition in hyper’s HTTP/1 Implementation

Listen to this article -  0:00

Cloudflare recently documented how its development team identified and fixed a rare bug in the widely used Rust HTTP library hyper that could silently truncate large HTTP responses while still returning a successful 200 OK status. The issue had existed for years, was triggered only under specific timing conditions, and has now been fixed upstream, prompting discussion among Rust practitioners about the incident and Cloudflare's handling of it.

The bug surfaced in Cloudflare Images during a redesign of its Workers Images binding. After rollout, some large image transformation requests intermittently returned truncated data despite reporting an HTTP 200 success.

In the technical breakdown, the team clarifies how they isolated the root cause and outlines their remediation path. Deanna Lam, product manager at Cloudflare, Diretnan Domnan, senior system engineer at Cloudflare, and Matt Lewis, senior system engineer at Cloudflare, summarize:

We spent six weeks chasing a nearly invisible bug — a race condition that occurred only under specific conditions — in the hyper library that impacted how the Images binding returned processed image data back to the client. In the end, it took four lines of code to fix it.

The Rust hyper library is a low-level networking library that implements the HTTP protocol, providing the core client and server functionality that many higher-level Rust web frameworks and applications rely on. It was started in 2014 by Sean McArthur and is released under the permissive MIT license.

After customers started reporting truncated images, the team noticed that responses returned HTTP 200 and the expected Content-Length, but in one case delivered only 200 KB of the expected 3.3 MB, making the source of the truncation difficult to identify.

The team systematically isolated each component in the request path by building a reliable reproduction, testing across hyper versions and environments, instrumenting every service, and using distributed tracing to progressively eliminate possible causes until the issue was narrowed to the Images service's HTTP response path.

Application-level tracing and logs showed no errors, but low-level kernel syscall tracing (strace) revealed that hyper was prematurely closing connections before buffered response data had been fully transmitted, confirming a timing-dependent race condition.

Cloudflare traced the bug to hyper's HTTP/1 dispatch loop, which incorrectly ignored an incomplete buffer flush and prematurely closed the connection, causing buffered response data to be lost under rare timing conditions. To fix the bug, the team added a deterministic test that reproduced the race condition and modified Hyper to ensure buffered data is fully flushed before closing the connection. Lam, Domnan, and Lewis add:

Our breakthrough came from using kernel-level tooling with strace, the one layer that records what actually happened on the socket. The underlying bug lived in the few milliseconds between a partial flush and a premature shutdown — a window that opened only after we made the system faster.

On Reddit, Martin Nordholts, a contributor to the Rust compiler, comments:

This is a known design flaw of async Rust. In sync Rust, if it compiles, it works (generally). In async Rust, that is not the case, unfortunately. One class of problems that contributes to that is silent cancellation. The article is one example of what bugs that can cause.

Highlighting how Cloudflare is not sponsoring Sean McArthur, who maintains hyper and other foundational Rust libraries, Jim Fuller writes:

Nice write-up by another $2b revenue company that does not appear to directly support developers that work on critical path to said revenue.

In a popular Hacker News thread, some practitioners focus on the Rust code:

This would have been flagged by Clippy lints `let_underscore_untyped` or `let_underscore_must_use`, which sadly are not enabled by default.

Others question Cloudflare's monitoring:

Cloudflare does not notice (until a customer complains) that they are sending broken responses at scale? I would have thought they would notice this from sampling and linting a few replies.

The fix and accompanying test have been merged into the hyper project and will be available in a future release, preventing the response truncation bug.

About the Author

Rate this Article

Adoption
Style

BT