CVE-2026-71380 Overview
CVE-2026-71380 is a denial-of-service vulnerability in the Erlang/OTP inetshttpd HTTP server. An unauthenticated remote attacker can exhaust all available worker processes by sending valid request headers with a large Content-Length and then stalling before the request body completes. The flaw is tracked under [CWE-772: Missing Release of Resource after Effective Lifetime]. Because httpd_request_handler:handle_info/2 cancels the request timeout after headers parse successfully and does not re-arm a timer while waiting for more body data, stalled connections remain indefinitely. Repeating this pattern against max_clients workers denies service to legitimate clients at negligible bandwidth cost.
Critical Impact
Unauthenticated attackers can occupy every httpd worker slot and deny service to legitimate clients with minimal network traffic.
Affected Products
- Erlang/OTP 17.0 through versions before 27.3.4.17 (inets 5.10 before 9.3.2.7)
- Erlang/OTP 28.0 through versions before 28.5.0.6 (inets 9.4 before 9.6.2.3)
- Erlang/OTP 29.0 through versions before 29.0.6 (inets 9.7 before 9.7.2)
Discovery Timeline
- 2026-09-01 - CVE-2026-71380 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-71380
Vulnerability Analysis
The inetshttpd request pipeline relies on a request timeout to bound how long a worker waits for client input. The function httpd_request_handler:handle_info/2 cancels that timeout as soon as any parse step completes, including header parsing. When the decoder subsequently signals that it needs more data, the clause re-arms the socket with {active, once} but does not restart any timer. Control returns to the process mailbox, which now blocks indefinitely on socket data that never arrives.
The request body decoder httpd_request:whole_body/2 returns a "need more data" continuation whenever the bytes received so far are less than the declared Content-Length. A well-formed request that stops midway through the body therefore parks the worker in a wait state with no fallback. The optional byte-rate reaper controlled by minimum_bytes_per_second would eventually reclaim the connection, but that option is not configured by default.
Root Cause
The root cause is missing resource lifetime management on the body-read path. After header parsing, the timeout that would enforce forward progress is dropped, and no equivalent timer is armed for subsequent socket activations. Combined with an unbounded max_clients pool being finite, an attacker who opens enough stalled requests exhausts the worker allocation and starves legitimate clients.
Attack Vector
The attack requires only network reachability to the httpd listener. An attacker opens a TCP connection, sends valid HTTP headers including a large Content-Length, sends fewer bytes than declared, and holds the connection open. Repeating this across enough parallel connections to match max_clients completes the denial of service. No authentication, user interaction, or protocol abuse is required.
# Patch excerpt: lib/inets/src/http_lib/http_internal.hrl
-define(HTTP_MAX_VERSION_STRING, 8).
-define(HTTP_MAX_METHOD_STRING, 20).
-define(HTTP_MAX_CONTENT_LENGTH, 100000000). %% 100 MB
--define(HTTP_MAX_BODY_READ_TIMEOUT, 60). %% seconds
+-define(HTTP_REQUEST_READ_TIMEOUT, 60). %% seconds
# Patch excerpt: lib/inets/src/http_server/httpd_conf.erl
-validate_config_params([{max_body_read_timeout, Value} | Rest])
- when is_integer(Value) andalso (Value > 0) ->
+validate_config_params([{request_timeout, Value} | Rest])
+ when (is_integer(Value) andalso (Value > 0));
+ Value =:= infinity ->
validate_config_params(Rest);
-validate_config_params([{max_body_read_timeout, Value} | _]) ->
- throw({max_body_read_timeout, Value});
+validate_config_params([{request_timeout, Value} | _]) ->
+ throw({request_timeout, Value});
Source: GitHub OTP Commit 81b453a. The fix renames max_body_read_timeout to request_timeout and applies it across the full request lifecycle, so a stalled body read now triggers a timeout instead of blocking forever.
Detection Methods for CVE-2026-71380
Indicators of Compromise
- Multiple concurrent TCP connections to the httpd port that complete the HTTP header exchange but never send a complete request body.
- httpd worker processes stuck in a receive state waiting on socket data, with max_clients saturation observed in application telemetry.
- Requests with unusually large Content-Length values followed by long idle intervals on the same connection.
Detection Strategies
- Monitor the ratio of accepted httpd connections to completed requests; a growing gap indicates half-completed request bodies.
- Instrument inets with process introspection to alert when worker count approaches max_clients for sustained periods.
- Correlate NetFlow or packet capture data to flag connections with declared Content-Length far exceeding actual bytes transferred over long durations.
Monitoring Recommendations
- Track httpd worker pool utilization and alert at defined thresholds below max_clients.
- Log per-connection byte-rate statistics and flag connections falling below expected throughput floors.
- Forward inets telemetry and reverse-proxy access logs to a centralized analytics platform for correlation across sources.
How to Mitigate CVE-2026-71380
Immediate Actions Required
- Upgrade Erlang/OTP to 27.3.4.17, 28.5.0.6, or 29.0.6 depending on your release branch, per the GitHub Security Advisory GHSA-5vp4-58hc-h8cc.
- Inventory internet-exposed services built on inetshttpd and prioritize their patching first.
- Place a reverse proxy in front of httpd that enforces request read timeouts and body completion deadlines.
Patch Information
The fix landed in commit 81b453a and is documented in the CNA CVE-2026-71380 Detail and the OSV Vulnerability EEF-CVE-2026-71380 record. The patch introduces a request_timeout configuration option that supersedes max_body_read_timeout and enforces a bound on the entire request lifecycle, including body reads. See the Erlang Version Order Documentation when selecting a target release.
Workarounds
- Set minimum_bytes_per_second in the httpd configuration so the periodic byte-rate check reclaims stalled workers even before patching.
- Reduce max_content_length to a value appropriate for expected client payloads so attackers cannot advertise oversized bodies.
- Terminate TLS and HTTP at a hardened proxy such as nginx or HAProxy that applies client_body_timeout and slow-loris protections upstream of inets.
# Example inets httpd config snippet enabling the mitigating options
{minimum_bytes_per_second, 64},
{max_content_length, 1048576},
{request_timeout, 60} %% available after upgrading to a fixed release
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

