Attack class
HTTP/2 Rapid Reset
Last updated: August 2026 · Cancelled streams stop counting · Reading time ~9 min

HTTP/2 Rapid Reset opens streams and cancels them immediately, so the server begins work it will never deliver while the concurrent-stream limit is never reached — cancelled streams stop counting. One connection can therefore drive far more requests per second than the protocol's own limit implies. It is tracked as CVE-2023-44487 and is a design consequence rather than an implementation bug.
HTTP/2 lets a client run many requests concurrently over one connection, and bounds that with a negotiated limit on concurrent streams. A client may also cancel a stream at any point by sending a reset frame.
Rapid Reset combines the two. Open a stream, send the request, cancel it immediately. The server has begun the work; the stream no longer counts against the concurrency limit; the next stream opens straight away.

At a glance
| Appliance | Property | Classic HTTP flood | Rapid Reset |
|---|---|---|---|
| Connections needed | Many, one or few requests each | Few; one connection carries thousands of requests | |
| What bounds the attacker | Connection setup cost | Almost nothing, once a connection exists | |
| Concurrency limit | Not applicable | Applies, and is never reached | |
| Visibility in connection counts | Obvious | Nearly invisible |
The last row is the operational problem. An estate watching connection counts sees a quiet afternoon while its backends saturate.
What it exhausts
Backend capacity, not bandwidth or connection state.
The server accepts a request and starts doing something with it: routing, authorising, querying a database, rendering. The cancellation arrives before that work finishes, and depending on the implementation the work may continue to completion anyway with the result discarded. Either way the resource has been spent.
Meanwhile the attacker’s cost is two small frames per request, over a connection that was established once. The asymmetry is extreme, and it is the reason the vector produced the requests-per-second records it did in late 2023.
How it differs from similar attacks
A classic HTTP flood needs many connections, because each one carries a modest number of requests. Connection count is therefore a usable signal, and connection-level rate limiting is a usable control.
Rapid Reset needs almost none. A handful of connections can drive an enormous request rate, so every control and every dashboard that reasons about connections is looking at the wrong number.
It is also unlike Slowloris, which holds connections open. This does the opposite — it churns through streams as fast as possible — and the two therefore defeat opposite defences.
Observable telemetry
- Requests per second far exceeding what the connection count would suggest. The single most diagnostic ratio.
- Reset frame rate rising, per connection and in aggregate.
- Backend latency and error rates rising while network-layer volume looks ordinary.
- Application logs showing large numbers of cancelled or aborted requests.
- Connection count flat or low, which is what makes it easy to miss.
Common false positives
Impatient real clients. Users navigating away, closing tabs or triggering a new search cancel streams legitimately. A browser prefetching and then abandoning does the same.
Client-side timeouts. An application with an aggressive timeout produces cancellations at scale during a slow period, which is a symptom of a problem rather than an attack.
The distinguishing feature is again the ratio: legitimate cancellation is a fraction of a connection’s streams. Attack traffic is nearly all cancellation, sustained.
Mitigation by layer
Patch first. Implementations added stream-cancellation accounting and limits in response to the disclosure, and an unpatched server is exposed to the vector in its cheapest form. The CVE dataset carries the record and its status.
Limit cancelled streams per connection. Count them, and close the connection when the count or rate exceeds a threshold derived from your own clients. This is the control that addresses the mechanism rather than its symptoms.
Rate-limit requests per connection, not only per address, because the vector’s whole point is that few addresses are involved.
Reduce request cost. Caching, query limits and pagination make every application-layer flood less effective, and unlike the controls above they help against vectors nobody has named yet.
Behavioural detection on request-to-connection ratio, which is the shape this attack has and ordinary traffic does not — the mechanism is covered in behavioural baselining.
Operational pitfalls
Watching connections. Every connection-based alert, limit and graph is blind here.
Blocking on reset frames alone. Cancellation is a normal protocol operation; a rule that treats any reset as hostile will refuse ordinary browsing.
Assuming a network-layer device sees it. The traffic is small, well-formed and low in volume. Nothing below the application layer distinguishes it.
Safe validation
Test with a client that opens a connection, issues requests and cancels each immediately, and measure three things: achieved requests per second against backend saturation, the connection count while that happens, and whether your monitoring alerted at all.
The third is usually the finding. Most estates discover that the attack ran to backend saturation without a single network-layer alarm, which is a monitoring gap rather than a mitigation one.
Isolation and authorisation requirements are in the test lab guide and authorised testing.
Frequently asked questions
- Is this a bug in a particular server?
- No, which is why it affected implementations broadly rather than one product. The behaviour follows from the protocol design: a cancelled stream stops counting against the concurrency limit, and that is reasonable in isolation. Implementations differ in how much work they had already committed before the cancellation arrived, which is why the impact varied while the vector did not.
- Does upgrading fix it?
- Patching is necessary and is not the whole answer. Vendors added counting of cancelled streams and limits on the cancellation rate, which bounds the vector. The durable protection is a per-connection limit on cancelled streams plus the ordinary request-cost hygiene that makes any application-layer flood less effective.
- Why did it produce such high request rates?
- Because the expensive part of an HTTP request from the attacker's side is establishing the connection, and Rapid Reset amortises that over thousands of requests. Once a connection exists, opening and cancelling a stream costs two small frames, so the achievable request rate per connection is bounded by bandwidth rather than by protocol limits.
- Does HTTP/3 have the same problem?
- The same shape of problem exists wherever a protocol allows cheap stream creation and cancellation, and implementations addressed it in the same period. The general defence is the same: count what was cancelled, and limit the rate at which a single connection may do it.
Sources
- CVE-2023-44487
NVD · 2023-10-10 · standard · accessed 2026-08-18
The record for the vector, published 10 October 2023.
- RFC 9113 — HTTP/2
IETF · standard · accessed 2026-08-18
Defines stream multiplexing, RST_STREAM and the SETTINGS_MAX_CONCURRENT_STREAMS limit the attack sidesteps.
- RFC 4732 — Internet Denial-of-Service Considerations
IETF · 2006-11 · standard · accessed 2026-08-18
Published: August 2026 · Last reviewed: August 2026
Reviewed means the sources above were re-read on that date; the text is only reissued when something material changed.
This guide is updated as vendors release new models and pricing. How we compare vendors