Security
Sep 10, 2026

CVE-2026-19203, CVE-2026-12611 & CVE-2026-19204: Three Jetty Protocol-Parser Flaws Hit EOL 9.4, 10.0, and 11.0

How a lone line feed, an HTTP/2 teardown race, and an unvalidated WebSocket opcode each let a remote unauthenticated client smuggle requests or take a Jetty server down, with no OSS fix for the 9.4, 10.0, and 11.0 lines.

Give me the TL;DR
CVE-2026-19203, CVE-2026-12611 & CVE-2026-19204: Three Jetty Protocol-Parser Flaws Hit EOL 9.4, 10.0, and 11.0

Between September 7 and 8, 2026, the Eclipse Jetty project disclosed three remote, unauthenticated vulnerabilities across Jetty's HTTP/1.1, HTTP/2, and WebSocket parsers, all assigned by the Eclipse CNA. CVE-2026-19203 is an HTTP request smuggling flaw (CWE-444) scored 8.3 High (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N). CVE-2026-12611 is an HTTP/2 denial of service (CWE-400) scored 8.7 High (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N). CVE-2026-19204 is a WebSocket heap-exhaustion DoS (CWE-770, CWE-789) scored 8.7 High on the same vector. All three affect Jetty 9.4, 10.0, and 11.0 to varying degrees; those three lines are past community end of life with no OSS fix available. Upstream fixes for the maintained lines shipped in Jetty 12.0.38 and 12.1.12 (12.1.11 for the HTTP/2 race).

Affected and unsupported? See NES for Jetty.

What are these CVEs?

Three different parsers, three different failure modes, one common theme: input that arrives before authentication, handled by protocol code that every connector runs.

CVE-2026-19203: lone-LF chunk parsing enables request smuggling

Classified CWE-444 (Inconsistent Interpretation of HTTP Requests), this lives in the jetty-http module's HttpParser. Jetty's HTTP/1.1 parser accepts a bare line feed as a line terminator inside chunked transfer coding, in the chunk-size line and its extensions, after chunk data, and in the trailer section. RFC 7230 permits a lone LF as a robustness measure for header lines, but chunk framing is defined strictly in terms of CRLF. A proxy, load balancer, or WAF that parses chunk framing strictly sees a different request boundary than Jetty does. Bytes the intermediary treats as the tail of one request become a second, attacker-controlled request on the backend connection. This is the classic front-end/back-end desync that enables cache poisoning, access-control bypass, and hijacking of other users' in-flight requests.

The mechanism is a single missed check. The parser's next() method tracks whether the previous byte was a carriage return, but when it meets an LF it clears that flag and returns the same LF token whether or not a CR preceded it. Every state that consumes chunk framing then accepts that token as end-of-line. Nothing records or rejects the missing carriage return.

CVE-2026-12611: HTTP/2 teardown race blocks every thread

Classified CWE-400 (Uncontrolled Resource Consumption), this lives in the http2-common and http2-server modules. By interleaving RST_STREAM and GOAWAY frames while a connection is being torn down, a client races the session termination logic. The race resets HTTP2Flusher.terminated (the flusher's "closed" marker) from its non-null value back to null after it has already been set. From that point, frames queued for the connection are accepted but never written or failed, so every thread performing a blocking response write on one of its streams waits forever. Repeat the sequence across connections and the whole server thread pool is exhausted. The server stops responding.

This one is reachable only on server connectors with HTTP/2 enabled (h2 over TLS with ALPN, or h2c). HTTP/1.1-only deployments are not exposed through this path.

CVE-2026-19204: unvalidated WebSocket opcode exhausts the heap

Classified CWE-770 (Allocation of Resources Without Limits) and CWE-789 (Memory Allocation with Excessive Size Value), this lives in the WebSocket frame parser. Jetty allocates a buffer of the size declared in a frame's payload length before it validates the frame's opcode. A frame carrying a reserved, unknown opcode is neither a data frame nor a control frame, so with auto-fragmentation enabled (the default) it bypasses the configured maximum frame size entirely. The parser allocates the full attacker-declared length, up to roughly 2 GiB per frame, for a frame it will then reject. Repeat over many connections and the JVM runs out of memory.

Severity and exploit conditions

All three carry Eclipse CNA CVSS v4.0 scores. NVD has these in Deferred status and has not published its own base-score analysis, so the CNA scores below are authoritative. We independently recomputed each vector with the cvss library and confirmed the published numbers.

CVE-2026-19203 (8.3 High, CWE-444)

CVE-2026-12611 (8.7 High, CWE-400) and CVE-2026-19204 (8.7 High, CWE-770/789)

Both DoS flaws share the same vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N.

For CVE-2026-12611, the trigger requires an HTTP/2 connector (h2 or h2c). For CVE-2026-19204, the peer must complete a WebSocket handshake and auto-fragmentation must be enabled, which it is by default.

Exploitation status

None of the three are in the CISA Known Exploited Vulnerabilities catalog as of September 10, 2026, and no active exploitation has been reported. There is no public weaponized proof of concept for any of them.

CISA's ADP enrichment records exploitation status as none for all three. Two are rated automatable no (CVE-2026-19203 and CVE-2026-12611); CVE-2026-19204 is rated automatable yes, which fits it: a single malformed WebSocket frame with a large declared length, repeated across connections, is a short deterministic loop. Technical impact is partial for all three. These are days old, so treat that as a snapshot, not a verdict. The smuggling flaw in particular follows the well-documented "Funky Chunks" research line that produced CVE-2026-2332 earlier this year, so the class is well understood by researchers even without a published PoC for this variant.

What an attacker can do

For CVE-2026-19203 (request smuggling), a remote unauthenticated attacker who can reach Jetty through a strictly-parsing front-end can:

  • Send a chunk header such as 3D;! terminated by a single \n. Jetty treats the LF as end-of-header and reads the following bytes as chunk data, while the intermediary places the boundary elsewhere. The trailing bytes, for example a complete GET /smuggled HTTP/1.1 request, are processed by Jetty as a separate request the intermediary never inspected.
  • Bypass access controls the front-end enforces, since the smuggled request never passes through the intermediary's authorization checks.
  • Poison shared caches and hijack other users' in-flight requests on the same backend connection.

For CVE-2026-12611 (HTTP/2 DoS): open an HTTP/2 connection, interleave RST_STREAM and GOAWAY frames during teardown to win the flusher race, then leave threads blocked on writes that never complete. Repeat until the thread pool is exhausted and the server stops answering any request, on any connector.

For CVE-2026-19204 (WebSocket DoS): complete a WebSocket handshake, then send frames with a reserved opcode and a payload length near 2 GiB. Each forces a full allocation before the opcode is rejected. A handful of connections drives the JVM to OutOfMemoryError.

All three sit at the transport layer, ahead of any route handler, middleware, or authentication check.

Who is affected?

The three CVEs do not share identical ranges. CVE-2026-19203 reaches back to 9.4.0; CVE-2026-12611 starts at 9.4.36; and CVE-2026-19204 does not affect 9.4 at all, because the 9.4 WebSocket parser rejects unknown opcodes on the first byte, before the payload length is read. The combined picture:

Jetty 9.4 reached community end of life on August 14, 2025. Jetty 10.0 and 11.0 both reached end of life on January 1, 2025. EOL dates are published on endoflife.date. Those three lines will not receive an upstream assessment or an OSS fix for any of these three CVEs, because nobody upstream is maintaining them. If you are on 9.4, 10.0, or 11.0, treat the exposure as real and unpatched.

The maintained 12.0.x and 12.1.x lines got their fixes in Jetty 12.0.38 and 12.1.12 (12.1.11 for the HTTP/2 race); the current releases are 12.0.39 and 12.1.13, both published in early September 2026. Upgrade to the current release rather than the exact fix version, so you pick up everything shipped since.

Mitigation guidance

Upgrading within a maintained 12.x line is a patch-level change. Moving off an EOL 9.4, 10.0, or 11.0 line to 12.x is a larger exercise: Jetty 12 introduced significant API and packaging changes (the Jakarta EE namespace, the new core handler architecture), which is exactly the migration friction that remediated EOL builds are meant to remove.

Related CVEs

These three join an active run of Jetty protocol-parser CVEs in NES-covered lines. Worth reviewing if Jetty 9.4, 10.0, or 11.0 is still in your fleet:

  • CVE-2026-2332: HTTP request smuggling via chunked extension quoted-string parsing, the earlier "Funky Chunks" variant that CVE-2026-19203 sits alongside.
  • CVE-2025-11143: improper URI validation in jetty-http allowing blocklist bypass in multi-component systems.
  • CVE-2026-6790: another recent Jetty protocol-layer issue affecting the maintained and EOL lines.
  • CVE-2026-10050: Jetty Digest authentication bypass via ISO-8859-1 handling. See our deep dive.
  • CVE-2026-5795: authentication bypass and privilege escalation in JaspiAuthenticator. See our deep dive.

For the version-support picture across all Jetty lines, see our Jetty end-of-life dates guide.

Taking action

If you run Jetty 12.0.x or 12.1.x, upgrade to the current release, 12.0.39 or 12.1.13, and you are done. Three High-severity protocol flaws closed in one bump.

The harder decision belongs to teams on Jetty 9.4, 10.0, or 11.0. Those lines went end of life on August 14, 2025 (9.4) and January 1, 2025 (10.0 and 11.0). They are exposed to these CVEs, and Jetty 12's API and namespace changes make "just upgrade" a real migration rather than a patch bump. Every future Jetty security release widens that gap, and an HTTP/1.1, HTTP/2, or WebSocket listener on an unmaintained line is a smuggled request or a memory-exhaustion loop away from an outage with no upstream advisory to point at.

HeroDevs builds NES for Jetty in partnership with Webtide, the team behind Jetty itself. NES for Jetty delivers drop-in replacement builds that resolve these vulnerabilities on end-of-life lines (9.4.64, 10.0.32, and 11.0.32 for this batch) without forcing a Jetty 12 migration you are not ready for.

See NES for Jetty to confirm coverage for your version, or talk to our team about scoping an end-of-life Jetty estate.

Table of Contents
Author
Greg Allen
Chief Technology Officer
Open Source Insights Delivered Monthly