CVE-2026-55737 Overview
CVE-2026-55737 is a signed-to-unsigned conversion error [CWE-195] combined with an out-of-bounds write in the Erlang/OTP runtime system (erts). An attacker who can supply a crafted Erlang External Term Format (ETF) binary to binary_to_term/1 can corrupt the BEAM virtual machine heap pointer and crash the VM. The flaw affects OTP releases from OTP 25.0 up to (but not including) OTP 29.0.4, OTP 28.5.0.4, and OTP 27.3.4.15, spanning erts 13.0 through 17.0.4, 16.4.0.4, and 15.2.7.11.
Critical Impact
A single crafted ETF payload delivered to any code path invoking binary_to_term/1 can terminate the BEAM VM, causing denial of service to the Erlang node and any application running on it.
Affected Products
- Erlang/OTP releases from OTP 25.0 before OTP 29.0.4
- Erlang/OTP 28.5.0.x before 28.5.0.4
- Erlang/OTP 27.3.4.x before 27.3.4.15 (erts 13.0 through 17.0.4, 16.4.0.4, 15.2.7.11)
Discovery Timeline
- 2026-07-27 - CVE-2026-55737 published to NVD
- 2026-07-30 - Last updated in NVD database
Technical Details for CVE-2026-55737
Vulnerability Analysis
The defect lives in the ETF decoder in erts/emulator/beam/external.c. When decoding a LARGE_TUPLE_EXT term, the validation pass decoded_size() reads the 32-bit arity field as unsigned using get_uint32(). The decode pass dec_term() reads the same field as a signed 32-bit integer using get_int32() and stores it in an int. The two passes disagree on the sign of any value with the high bit set.
An arity wire value of 0x80000000 passes validation as 2147483648 but decodes as -2147483648. The subsequent expression hp += n then moves the BEAM heap allocation pointer backward by roughly 8 GB rather than forward. Neither pass enforces the runtime tuple-arity limit MAX_ARITYVAL. In practice the VM detects an impossible heap size and aborts, denying service to the Erlang node.
Root Cause
The root cause is a signed/unsigned integer conversion mismatch [CWE-195] between two code paths that parse the same ETF field. Because neither pass validates against MAX_ARITYVAL, oversized arity values reach heap arithmetic and produce an out-of-bounds write against the BEAM heap pointer.
Attack Vector
Exploitation requires the attacker to deliver a crafted ETF binary to any code path that invokes binary_to_term/1. Although the malicious LARGE_TUPLE_EXT term requires large padding when uncompressed, the compressed-ETF envelope shrinks it to a small on-the-wire payload. Any service that accepts external term data — distributed Erlang traffic, cookies, message queues, RPC endpoints — is a potential entry point.
#include "sys.h"
#include "erl_vm.h"
#include "global.h"
+#include "erl_term.h"
#include "erl_process.h"
#include "error.h"
#include "external.h"
Source: GitHub OTP Commit c5210b42. The patch introduces erl_term.h in external.c so that arity checks can reference MAX_ARITYVAL and reject values that exceed the runtime tuple-arity limit before heap arithmetic occurs.
Detection Methods for CVE-2026-55737
Indicators of Compromise
- Unexpected BEAM VM aborts or erl_crash.dump files referencing impossible heap sizes on Erlang nodes accepting external term data.
- Inbound network payloads containing compressed ETF envelopes (magic byte 131 followed by tag 80) that decompress into LARGE_TUPLE_EXT terms with arity fields where the high bit is set.
- Process supervisors restarting Erlang nodes repeatedly after receiving crafted client traffic.
Detection Strategies
- Monitor Erlang application logs and OS-level process supervisors for abnormal BEAM termination signatures shortly after binary_to_term/1 invocations on untrusted input.
- Inspect network traffic to services that accept ETF payloads for compressed envelopes containing LARGE_TUPLE_EXT tags (0x69) with 32-bit arity values greater than MAX_ARITYVAL ((1 << 26) - 1).
- Instrument application code paths that call binary_to_term/1 on external data to log input size, decompressed size, and any decoder errors.
Monitoring Recommendations
- Alert on repeated BEAM node crashes across a cluster within a short time window, which suggests a targeted denial-of-service attempt.
- Track versions of erts deployed across Erlang fleets and flag any host running erts earlier than 17.0.4, 16.4.0.4, or 15.2.7.11.
- Correlate crash timing with inbound connection metadata to identify the source of malicious ETF payloads.
How to Mitigate CVE-2026-55737
Immediate Actions Required
- Upgrade to Erlang/OTP 29.0.4, 28.5.0.4, or 27.3.4.15, corresponding to erts 17.0.4, 16.4.0.4, or 15.2.7.11.
- Audit application code for calls to binary_to_term/1 that accept data from untrusted sources and route those calls to binary_to_term/2 with the {safe, true} option where feasible.
- Restrict network access to distributed Erlang ports and any application listener that deserializes ETF from external clients.
Patch Information
The fix is committed in the Erlang/OTP repository as commit c5210b42a9d3d96f3d25601942ce8122be0f3761 and tracked in GHSA-446w-268v-9462. Fixed releases are OTP 29.0.4, 28.5.0.4, and 27.3.4.15. Additional details are available at the CNA advisory and the OSV entry.
Workarounds
- Where patching is not immediately possible, replace binary_to_term/1 on external input with binary_to_term/2 using the {safe, true} option and reject terms whose decompressed size exceeds a conservative limit.
- Terminate untrusted ETF at an application-layer proxy that validates the term tag stream and rejects LARGE_TUPLE_EXT (tag 105) frames with arity greater than MAX_ARITYVAL.
- Firewall distributed Erlang ports (EPMD and node ports) so that only trusted peers can deliver ETF messages to affected nodes.
# Verify installed erts version and confirm it matches a patched release
erl -eval 'io:format("erts: ~s~nOTP: ~s~n", [erlang:system_info(version), erlang:system_info(otp_release)]), halt().' -noshell
# Prefer safe decoding for any untrusted ETF payload
# Erlang shell:
# binary_to_term(Bin, [safe]).
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

