HTTP/2 Rapid Reset was disclosed on 10 October 2023, when Google, Cloudflare and AWS jointly reported request floods of 398, 201 and 155 million requests per second, each a record for its network at the time. It still matters because the flaw is in how servers count HTTP/2 streams rather than in any one product, so every new proxy, gateway and origin stack has to be checked for it, which is why it remains one of the Layer 7 vectors a thorough DDoS test exercises. Tracked as CVE-2023-44487, it abuses stream multiplexing: the client opens a request stream and immediately cancels it with a RST_STREAM frame, then repeats at high speed over a single connection. The server does the work of setting up and tearing down each stream while the client pays almost nothing, so a small number of connections generates enormous request churn.
Why the concurrency limit did not hold
HTTP/2 gives the server one brake on a single connection: SETTINGS_MAX_CONCURRENT_STREAMS, typically set to around 100. A client may have at most that many streams open at once. The limit was designed for well-behaved clients that wait for responses, and it assumes a stream stays open while the server works on it.
RST_STREAM breaks that assumption. The moment the client sends the reset, the stream is closed from the protocol's point of view and stops counting against the limit, so the client may open the next one in the same packet. The server, meanwhile, has often already parsed the headers, run the routing logic and, in a reverse proxy, forwarded the request upstream. That work is not undone by the cancel. In HTTP/1.1 a client that abandons a request has to close the whole TCP connection and open a new one; in HTTP/2 the abandon costs one small frame.
That is why the record numbers came from a modest fleet. Cloudflare reported that its 201 million request-per-second peak came from a botnet of roughly 20,000 machines, far fewer than earlier floods of a similar rate had needed. The attack is not about holding resources open, as a low-and-slow attack does; it is about turning each connection into a request generator the concurrency limit cannot see.
What the fixes changed
The patches shipped in October 2023 took different routes. Several servers began counting resets per connection and closing the connection with a GOAWAY frame once cancellations made up an implausible share of its streams. Go's HTTP/2 server additionally capped the number of request handlers running at once to the advertised stream limit, so cancelled streams could no longer pile up handler work behind the client's back.
Neither approach is a single setting you can confirm from a version string. A patched origin behind an unpatched load balancer is still exposed, because the component that terminates HTTP/2 is the one that does the counting. And an edge that terminates HTTP/2 correctly may still have forwarded the request to the origin over a separate connection before the reset arrived, so the origin pays for work the edge already threw away. Origin logs show this as a surge of client-closed responses (nginx logs it as status 499) with no matching rise in completed requests.
Its 2024 cousin, the HTTP/2 CONTINUATION flood, abuses the same protocol from the opposite direction: it hides from request counters, while Rapid Reset inflates them.
What a DDoS test measures
A test drives open-and-cancel churn over a small number of HTTP/2 connections against each hop that terminates the protocol, and raises the cancel rate in steps. Three readings come out of it. First, the reset ceiling: how many cancelled streams a connection may send before the server answers with GOAWAY, and whether that number is set deliberately or is simply the library default. Second, upstream leakage: whether requests cancelled at the edge still reach the origin, visible as client-closed entries in origin logs during the run. Third, the cost to real users: the goodput of a parallel legitimate session while the churn runs.
A clean result is a connection closed within a bounded number of resets at the first hop, with nothing arriving at the origin. A patch level is a claim; that measurement is the proof.
How this sits beside the other request-layer vectors a test exercises is laid out in application-layer DDoS testing.