CVE-2026-59246 Overview
CVE-2026-59246 is a resource exhaustion vulnerability [CWE-770] in elixir-mint/mint, the Elixir HTTP client library widely used in the BEAM ecosystem. A malicious HTTP/2 server can force a connected Mint client to accumulate an unbounded chain of empty header-block fragments, driving the Erlang VM to memory exhaustion and eventual out-of-memory termination.
The flaw affects mint versions 0.1.0 through 1.9.1 and is fixed in 1.9.2. Exploitation requires only that a client connect to an attacker-controlled HTTP/2 endpoint, which can be reached directly, through an attacker-controlled redirect, via Server-Side Request Forgery (SSRF), or via a man-in-the-middle position.
Critical Impact
A remote HTTP/2 peer can crash any BEAM node running the Mint client by streaming zero-length CONTINUATION frames, causing denial of service to Elixir and Erlang applications that depend on Mint for outbound HTTP traffic.
Affected Products
- elixir-mint/mint versions 0.1.0 through 1.9.1
- Downstream Elixir libraries that embed Mint (for example, Finch, Tesla with the Mint adapter, and Req)
- BEAM applications performing outbound HTTP/2 requests via Mint
Discovery Timeline
- 2026-07-14 - CVE-2026-59246 published to NVD
- 2026-07-15 - Last updated in NVD database
Technical Details for CVE-2026-59246
Vulnerability Analysis
The defect resides in Mint.HTTP2.handle_continuation/3 inside lib/mint/http2.ex. When an HTTP/2 stream begins with a HEADERS frame that does not set END_HEADERS, the connection must accept subsequent CONTINUATION frames until one of them terminates the header block.
Mint accumulates each fragment into conn.headers_being_processed by nesting the previous accumulator with the new chunk in an iodata list. Every frame received adds one level of cons-cell nesting to the accumulator, regardless of payload size.
The only bound applied is Mint.HTTP2.assert_header_block_within_max_size/2, which sums the byte size of received fragments. Because HTTP/2 allows a CONTINUATION frame to carry a zero-byte payload, empty frames bypass the size check while still growing the accumulator structurally.
Root Cause
The root cause is missing validation of the frame count and structural growth of the header-block accumulator. The guard measures bytes but not the number of iodata nodes, allowing an attacker to expand memory without ever advancing the size counter. This is a classic Allocation of Resources Without Limits or Throttling weakness [CWE-770].
Attack Vector
A malicious HTTP/2 server opens a stream by sending a HEADERS frame without the END_HEADERS flag. The server then transmits an unbounded sequence of zero-length CONTINUATION frames on the same stream and never sets END_HEADERS.
On the client side, each frame appends one cons cell to conn.headers_being_processed. Sustained bandwidth from the peer drives linear memory growth in the BEAM process until the operating system terminates the node.
conn = put_in(conn.headers_being_processed, nil)
callback.(conn, responses, hbf, stream)
else
- new_size = acc_size + byte_size(hbf_chunk)
- conn = assert_header_block_within_max_size(conn, new_size)
+ if byte_size(hbf_chunk) == 0 do
+ # An empty fragment does not contribute header-block data. Keeping the
+ # existing accumulator avoids adding an unbounded number of empty
+ # iodata nodes when END_HEADERS is withheld.
+ {conn, responses}
+ else
+ new_size = acc_size + byte_size(hbf_chunk)
+ conn = assert_header_block_within_max_size(conn, new_size)
- conn =
- put_in(
- conn.headers_being_processed,
- {stream_id, [hbf_acc, hbf_chunk], callback, new_size}
- )
+ conn =
+ put_in(
+ conn.headers_being_processed,
+ {stream_id, [hbf_acc, hbf_chunk], callback, new_size}
+ )
- {conn, responses}
+ {conn, responses}
+ end
end
end
Source: GitHub Commit 5779de1. The patch short-circuits handling when byte_size(hbf_chunk) == 0, returning the connection unchanged and preventing accumulator growth for empty fragments.
Detection Methods for CVE-2026-59246
Indicators of Compromise
- Rapid, sustained memory growth in a BEAM node performing outbound HTTP/2 requests, followed by out-of-memory termination.
- Long-lived HTTP/2 streams to external hosts where no full response is ever delivered, and inbound traffic consists of frames with Type=9 (CONTINUATION) and Length=0.
- Repeated crash-loop restarts of Elixir services (Finch pools, Req clients, Tesla with Mint adapter) after outbound calls to attacker-controlled or redirected endpoints.
Detection Strategies
- Inspect network telemetry for HTTP/2 flows where HEADERS frames lack the END_HEADERS flag and are followed by many CONTINUATION frames with zero-length payloads.
- Correlate BEAM process memory metrics with outbound HTTP/2 connection duration; flag connections whose lifetime and byte-in count diverge sharply from response size.
- Review application logs for Mint.HTTPError and abnormal termination of HTTP client supervisors tied to specific remote hosts.
Monitoring Recommendations
- Emit metrics for erlang:memory/0 and per-process heap size on nodes that use Mint, with alerting on sustained upward slope.
- Enforce and monitor egress allow-lists for services that make outbound HTTP calls to reduce exposure to attacker-controlled hosts and SSRF pivots.
- Log the mint version deployed with each release and alert when versions below 1.9.2 reach production.
How to Mitigate CVE-2026-59246
Immediate Actions Required
- Upgrade mint to version 1.9.2 or later in all Elixir and Erlang applications, including transitive dependencies through Finch, Req, and Tesla.
- Audit outbound HTTP call sites for SSRF exposure and restrict redirect following to trusted hosts until the upgrade lands.
- Terminate long-lived HTTP/2 client sessions to untrusted endpoints and enforce request timeouts.
Patch Information
The fix landed in commit 5779de1666344b32aefc4354184ea07f902f73ce and shipped in mint 1.9.2. See the GitHub Security Advisory GHSA-8pf6-g464-h6h9 and the CNA advisory from the Erlang Ecosystem Foundation for full disclosure details. Cross-reference tracking is available in the OSV entry EEF-CVE-2026-59246.
Workarounds
- Set aggressive receive timeouts on Mint requests so idle streams close before they can exhaust memory.
- Restrict outbound HTTP/2 traffic to known-good hosts using an egress proxy or firewall policy.
- Disable HTTP/2 negotiation in Mint clients and fall back to HTTP/1.1 for connections to untrusted origins until patching is complete.
# Update the dependency in mix.exs and refresh the lockfile
# {:mint, "~> 1.9.2"}
mix deps.update mint
mix deps.get
mix deps.compile mint
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

