Introduction
As few as nine bytes sent over a TCP connection can force a Netty-based server to allocate 16 MiB of unpooled direct memory, and the default SNI handler configuration does nothing to stop it. CVE-2026-45416 is a denial-of-service condition in Netty's SslClientHelloHandler. A crafted TLS ClientHello message gets past a disabled length guard and triggers a large memory pre-allocation, which stays in place until the attacker's connection closes.
Netty is the asynchronous network I/O framework underneath much of the Java ecosystem, including infrastructure components like Spring Boot, gRPC, Cassandra drivers, and Elasticsearch clients. It has roughly 35,000 GitHub stars and adopters including Airbnb and Apple, so a vulnerability in its TLS handling reaches widely across the industry.
Technical Information
Root Cause
The vulnerability lives in SslClientHelloHandler.decode() within the io.netty:netty-handler package. When a TLS ClientHello message arrives, the method reads the 24-bit handshake length field from the TLS record header. If the ClientHello does not fit entirely within the first TLS record, the code at line 161 eagerly allocates a buffer sized to the declared handshake length:
ctx.alloc().buffer(handshakeLength)
The intended safety mechanism is a guard at line 140:
handshakeLength > maxClientHelloLength && maxClientHelloLength != 0
This guard is supposed to reject oversized ClientHello messages. But the three most commonly used constructors for SNI handling all pass maxClientHelloLength=0 and handshakeTimeoutMillis=0:
| Constructor | maxClientHelloLength | handshakeTimeoutMillis |
|---|---|---|
SniHandler(Mapping) | 0 | 0 |
SniHandler(AsyncMapping) | 0 | 0 |
AbstractSniHandler() | 0 | 0 |
When maxClientHelloLength is 0, the condition maxClientHelloLength != 0 evaluates to false, so the whole guard short-circuits whatever the handshakeLength value is. The handshakeTimeoutMillis=0 setting also means no timeout is ever scheduled, so nothing reclaims the buffer if the handshake stalls.
This is a textbook case of CWE-770 (Allocation of Resources Without Limits or Throttling). An untrusted network input (the 24-bit handshake length field) is used directly as the allocation size with no effective upper bound.
Attack Flow
-
The attacker opens a TCP connection to a Netty-based service that terminates TLS using one of the default SNI handler constructors.
-
The attacker sends a TLS record containing a ClientHello with the 24-bit handshake length field set to 16,777,215 (0xFFFFFF), the maximum value. Only the TLS record header and the length field need to be present. The actual ClientHello payload can be minimal or absent, so the whole message can be as small as nine bytes.
-
The
decode()method reads the handshake length. The guard at line 140 evaluates16777215 > 0 && 0 != 0, which reduces totrue && false, orfalse. The guard does not trigger. -
The code proceeds to line 161 and calls
ctx.alloc().buffer(16777215). Because 16 MiB exceeds Netty's default pooled chunk size, this becomes an unpooled (direct memory) allocation, performed immediately on the hot path. -
The handler holds on to the allocated buffer, waiting for the rest of the ClientHello data, which will never arrive. Because
handshakeTimeoutMillisis 0, no timeout is scheduled to clean up the allocation. -
The attacker repeats this across many connections. Each connection consumes approximately 16 MiB of direct memory, an amplification factor of approximately 1.86 million to one (9 bytes in, 16 MiB allocated).
-
The accumulated memory pressure leads to
OutOfMemoryError, container OOM kills, or severe performance degradation, and the service goes down.
The CVSS v3.1 vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (score 7.5) reflects network exploitability, low complexity, no authentication requirement, and high availability impact.
Why This Is Subtle
The first bytes of the attack look like a legitimate TLS ClientHello. Standard network monitoring tools that inspect TLS traffic at the protocol level may not flag the oversized length field as anomalous, since the TLS specification permits large handshake messages. The TLS protocol itself is not at fault. The bug is in Netty, which allocates the buffer before it validates the full message.
The memory consumed is also off-heap direct memory, not JVM heap memory, so standard JVM heap monitoring and garbage collection metrics will not show the growing pressure. Operators need to monitor direct memory usage specifically (e.g., via java.nio.BufferPoolMXBean) to detect this condition.
Affected Systems and Versions
The vulnerability affects the io.netty:netty-handler package in two version branches:
| Branch | Vulnerable Versions | Fixed Version |
|---|---|---|
| 4.1.x | All versions prior to 4.1.135.Final | 4.1.135.Final |
| 4.2.x | 4.2.0.Final through 4.2.14.Final | 4.2.15.Final |
The vulnerable configuration requires one of the default SNI handler constructors: SniHandler(Mapping), SniHandler(AsyncMapping), or AbstractSniHandler(). These constructors pass maxClientHelloLength=0, which disables the length guard. Custom configurations that explicitly set a nonzero maxClientHelloLength may be partially protected, though upgrading is still the recommended action.
Netty often arrives as a transitive dependency, so organizations should audit their dependency trees with tools like Maven's dependency:tree or Gradle's dependencies task to find every path that resolves to a vulnerable version of io.netty:netty-handler.
Vendor Security History
Netty has had a concentrated run of security disclosures. The Cybersecurity Help security bulletin SB2026060813 cataloged 22 vulnerabilities published around the same time as CVE-2026-45416. Notable recent CVEs include:
| CVE | Type | Severity |
|---|---|---|
| CVE-2026-45416 | SNI handler memory pre-allocation DoS | High (7.5) |
| CVE-2026-44248 | MQTT Decoder DoS | Reported |
| CVE-2026-42578 | DoS in netty-handler | Reported |
| CVE-2026-33871 | DoS vulnerability | Reported |
| CVE-2025-25193 | DoS (up to 4.1.118.Final) | Reported |
| GHSA-389x-839f-4rhx | DoS via environment file on Windows | Reported |
The common thread across these disclosures is denial of service in protocol decoders, where Netty reads untrusted length fields from network input and allocates resources without effective bounds. Organizations that depend on Netty should plan to patch multiple CVEs in one batch rather than one at a time, and should consider auditing other resource allocation paths in the framework for the same flaw.
The Netty project publishes security advisories through the GitHub Security Advisory system and follows responsible disclosure practices. Maintainer chrisvest published the CVE-2026-45416 advisory on June 5, 2026.
References
- NVD: CVE-2026-45416
- CVE Record: CVE-2026-45416
- GitHub Security Advisory: GHSA-x4gw-5cx5-pgmh
- GitLab Advisory: CVE-2026-45416
- Tenable: CVE-2026-45416
- Netty Release: 4.1.135.Final
- Netty Release: 4.2.15.Final
- Netty Security Advisories
- SB2026060813: Multiple Vulnerabilities in Netty
- Netty Adopters
- CISA Known Exploited Vulnerabilities Catalog



