October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

Five Reverse-Proxy Failure Boundaries—and How a Rust Project Fixed Them

A Rust proxy project exposed five failure boundaries where protocol translation, route choice, breaker state, client uploads and header ordering mattered.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A reverse proxy can fail in ways that are easy to misdiagnose because it sits between two parties and two protocols. In a 2025 account of the Rust project ferryman-edge, developer Bipin C describes five bugs involving HTTP version translation, route selection, circuit-breaker probes, streamed request bodies and trusted headers. They are not bugs unique to Rust or necessarily present in every proxy; they show how mistakes at the proxy’s boundaries can turn a client-side problem into an upstream failure—or route a request somewhere it should never go.

What ferryman-edge does

Bipin C describes ferryman-edge as a small layer-7 reverse proxy written in Rust. Its request path includes mutual TLS authentication, RS256 bearer-token verification, per-tenant GCRA rate limiting, and an upstream circuit breaker with active health checks. Certificates and routes can be hot-reloaded with SIGUSR1; connections already established retain their handshake TLS configuration, while new connections use the reloaded configuration.

The author says reusable components were published as ferryman-edge-core and gives cargo install ferryman-edge as the installation command. These are descriptions in the author’s 2025 article; current package availability and versions are not established here. Read Bipin C’s account.

1. HTTP/2 clients received 502s when the upstream used plain HTTP

The listener negotiated HTTP/2 or HTTP/1.1 with clients using ALPN, but the upstream connection was plain http://. The proxy carried the inbound request’s HTTP/2 version through to Hyper’s legacy client, which rejected an HTTP/2-versioned request on an HTTP/1 connection with UserUnsupportedVersion. The client-facing and upstream-facing protocols are separate; supporting h2 at the listener does not make a plain HTTP upstream speak h2.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The fix described by C resets the request version to HTTP/1.1 before forwarding. The response version also needs normalization: a Python http.server upstream could return HTTP/1.0, which otherwise led to an HTTP/1.0 status line being sent to an HTTP/1.1 keep-alive client. C says an end-to-end test exercises a real h2 request.

2. An open breaker sent a specific route to a broader backend

Routes use longest-prefix matching on path-segment boundaries. The original lookup combined matching with a check that the selected upstream was routable. If the most-specific route matched but its breaker was open, iteration could continue to a broader catch-all route. In C’s example, a request for /svc-a/x fell through to / after the /svc-a breaker opened—a change in destination, not merely a temporary failure.

The fix separates identity from availability: first choose the most-specific matching route, then check whether that route is routable. If it is not, return 503 rather than silently sending the request to a different backend. A breaker should affect whether the winning route can serve the request, not which route wins.

3. Multiple requests became half-open recovery probes

After a circuit breaker’s cooldown, one request should be allowed to test whether the upstream has recovered. C says the implementation used a compare-and-swap on a state byte, but an ABA window could allow more than one request through as a half-open probe. The shipped approach uses the last-transition timestamp as the compare-and-swap token instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The article reports a concurrency test that released eight threads behind a barrier, repeated the test 200 times, and checked that exactly one request was admitted each time. It also describes a zero-second cooldown edge case: requests in the same second could all appear eligible. The configuration now rejects a zero cooldown, according to C.

4. An abandoned client upload could trip a shared upstream breaker

With streaming request bodies, reading the body is part of the upstream call. C reports that a client disconnect or a body-length-limit error could therefore be counted as an upstream failure. Because the breaker was shared for a route, one authenticated tenant could affect other tenants using it.

The fix walks the error source chain to identify client-body errors—including the configured length-limit error and Hyper user errors—and distinguish them from upstream failures. The author also describes separating deadlines: body reading receives its own deadline and returns 408 on timeout; the upstream timeout starts once the body is available, with a wrapper recording stream completion where needed. Reading the body before route lookup also means a client-side failure does not consume a half-open recovery probe.

5. Hop-by-hop stripping removed the proxy’s tenant header

After verifying a JWT, the proxy adds x-ferryman-tenant using the token subject, first removing any client-supplied value. It then strips hop-by-hop headers and headers named by the Connection header. Because sanitization originally happened after the trusted header was stamped, a client could send Connection: keep-alive, x-ferryman-tenant and cause the proxy’s own tenant header to be stripped.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The correction is ordering: strip hop-by-hop and connection-nominated headers first, then add the trusted tenant identity. C says the regression test covers HTTP/1.1; HTTP/2 forbids the Connection header.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Other project-specific fixes the author mentions

  • Tokio timer guard: A select! guard was checked when selection began rather than when the timer branch fired. C says the relevant flag is now checked inside that branch.
  • JWT issuer validation: The article says jsonwebtoken 9 checks issuer and audience only when those claims are present. To require an issuer, the implementation also needs required_spec_claims to include iss.
  • Process and build environment: C reports that Linux process-name truncation affected pgrep -x, and that a glibc mismatch between a trixie builder and bookworm runtime led the project to pin its builder to bookworm. These are observations about this project’s setup, not universal guarantees about those tools or platforms.

What the author measured—and what remains unmeasured

The figures below are reported by Bipin C in the article, interpreted as published in 2025 from search metadata. They have not been independently reproduced.

Reported result Qualification
3,725 of 3,725 requests succeeded In a 60-second hot-reload run using a release build, eight curl workers and two SIGUSR1 signals. The author says every request used a fresh curl process to exercise a new mTLS handshake.
0.68 µs cache-hit JWT verification; about 150 µs cache-miss verification Attributed to the author’s Criterion measurements.
16 MB RSS Reported after the hot-reload run described above.
119 ms TLS-handshake p99 Not representative according to the author, because client and server shared one machine.
50,000 requests per second Target, not a measured result. The available wrk/wrk2 setup could not present a client certificate, and the author said an mTLS-capable load generator was still needed.

The common thread: keep failure attribution intact

Each fix protects a boundary. The proxy must preserve which protocol belongs to each connection, which route actually matched, whether a failure came from the client or upstream, who is allowed to probe a recovering backend, and whether a header is trusted or client-controlled. Blurring any of those distinctions can turn an ordinary failure into a security, availability or routing problem.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.