If you run a JVM service that speaks HTTP/2, the io.netty:netty-codec-http2 Maven artifact is almost certainly in your dependency tree, and keeping it patched is the single most important thing you can do to avoid a known denial-of-service class. Netty is the async networking layer under gRPC-Java, Spring WebFlux, Elasticsearch clients, and a long list of other libraries, so most teams pull netty-codec-http2 in transitively without ever declaring it. That invisibility is the problem: you cannot patch what you do not know you have.
What netty-codec-http2 does and why it is everywhere
Netty is a high-performance, event-driven network application framework for the JVM. It is split into focused modules, and netty-codec-http2 is the one that implements the HTTP/2 protocol — frame parsing, stream multiplexing, flow control, and header (HPACK) compression. When a library needs to serve or consume HTTP/2, it depends on this codec rather than reimplementing the protocol.
Because gRPC-Java is built on Netty, any service using gRPC pulls in netty-codec-http2 transitively. The same goes for reactive HTTP clients and servers. Run mvn dependency:tree on a typical microservice and you will usually find the artifact nested several levels below your direct dependencies, its version dictated by whichever library declared it.
The HTTP/2 Rapid Reset vulnerability (CVE-2023-44487)
The most significant vulnerability affecting this artifact is CVE-2023-44487, known as HTTP/2 Rapid Reset. It is a protocol-level denial-of-service flaw, not a Netty-specific bug, but Netty was among the many HTTP/2 implementations that needed a fix. It carries a CVSS score of 7.5 (high).
The attack abuses a legitimate HTTP/2 feature: stream cancellation. A client opens a stream by sending a HEADERS frame with a new stream identifier, then immediately cancels it with an RST_STREAM frame. Because the client cancels the stream itself, the server's normal concurrent-stream limit never kicks in — from the protocol's point of view the stream is already closed. An attacker automates this into a flood, opening and instantly resetting streams by the thousands. Each request still costs the server backend work to set up and tear down, so the machine burns CPU and memory on requests that produce no useful response, starving legitimate traffic.
Google, Cloudflare, and Amazon reported this being exploited in the wild between August and October 2023 at record-breaking request rates. The fix in Netty landed in version 4.1.100.Final. If your netty-codec-http2 resolves to anything earlier than that, you are running the vulnerable code path.
Related HTTP/2 abuse patterns
Rapid Reset is not the only way to weaponize HTTP/2 stream lifecycle behavior. A later class of issue, sometimes described under the "MadeYouReset" research, showed that servers can be tricked into resetting streams themselves through malformed or timing-sensitive frame sequences, achieving a similar resource-exhaustion effect while sidestepping some Rapid Reset mitigations. The Netty project published advisories and follow-up hardening for these patterns.
The takeaway is not to memorize every advisory ID but to understand the shape of the risk: HTTP/2's stream multiplexing gives clients cheap ways to create server-side work, and any codec that does not bound that work per connection is exposed. Staying on a current 4.1.x release of netty-codec-http2 is how you inherit the accumulated mitigations rather than reinventing them.
How to find which version you actually run
The declared version in your POM is often not the version that resolves, because Maven's nearest-wins resolution and any dependency management can override it. Ask Maven directly:
mvn dependency:tree -Dincludes=io.netty:netty-codec-http2
That prints only the branches where the artifact appears, along with the resolved version and which dependency dragged it in. If you see something below 4.1.100.Final, plan the upgrade.
For a whole build, the enforcer plugin can fail the build when a banned version slips in:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>ban-vulnerable-netty</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>io.netty:netty-codec-http2:(,4.1.100.Final)</exclude>
</excludes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
How to upgrade safely
The cleanest way to move all Netty modules together is to import the Netty BOM (bill of materials) so every io.netty artifact resolves to one consistent version:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>4.1.115.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Pinning through the BOM avoids the classic mixed-version breakage where netty-codec-http2 moves to a new release but netty-common or netty-handler stays behind and you hit a NoSuchMethodError at runtime. Verify the version you pin is current at upgrade time; the 4.1.x line receives ongoing releases, so pick the latest stable rather than copying a number from a blog.
After bumping, run your integration tests against real HTTP/2 traffic. The protocol behavior is subtle and a mismatched transport module tends to fail at connection setup rather than compile time.
Where automation earns its keep
Because netty-codec-http2 is almost always transitive, manual tracking does not scale past a handful of services. This is the core job of software composition analysis: continuously inventory every artifact in the resolved tree, match it against advisory databases, and tell you which service, in which module, is running the vulnerable version. Our SCA overview walks through how that inventory is built on each commit. An SCA tool such as Safeguard can also flag whether your code paths actually exercise the vulnerable HTTP/2 server, so you can prioritize the internet-facing gateway over the internal batch job that never accepts inbound HTTP/2.
If you maintain other Maven services, the same discipline applies to every widely-embedded library; our Java security best practices post covers the broader pattern of governing transitive risk across a JVM estate.
FAQ
Do I need to declare netty-codec-http2 directly to patch it?
Usually not. The better approach is to import the netty-bom in your dependencyManagement, which forces every transitive io.netty artifact — including netty-codec-http2 — to the version you choose without you declaring each module as a direct dependency.
Is CVE-2023-44487 a Netty bug or an HTTP/2 bug?
It is fundamentally an HTTP/2 protocol design issue that affected nearly every implementation, including Netty, nginx, and cloud load balancers. Netty's fix in 4.1.100.Final bounds the rate of stream resets per connection so the flood can no longer exhaust resources.
Can I mitigate without upgrading?
Netty lets you limit the number of RST frames accepted per connection over a time window with a custom Http2FrameListener or channel handler, which blunts the attack. Upgrading is still the correct fix, because it applies the maintained, tested mitigation rather than a hand-rolled one you have to keep current yourself.
How often should I re-check the version?
On every build. Transitive versions drift as you bump the libraries that depend on Netty, so a service that was clean last quarter can regress silently when an unrelated dependency downgrades the codec. Automated scanning on each commit is the only reliable way to catch that.