CVE-2026-59646 is a high severity remote denial of service in the DTLS code of Bouncy Castle for Java. The handshake reassembler allocates a buffer from an unchecked 24-bit length before authentication. Fixed in 1.85, LTS 2.73.12 and bctls-fips 1.0.24, 2.0.24 and 2.1.24.
What's affected
- Bouncy Castle for Java: before 1.85.
- Bouncy Castle for Java LTS: before 2.73.12.
- Bouncy Castle FIPS: before bctls-fips 1.0.24 (1.0.X), 2.0.24 (2.0.X) and 2.1.24 (2.1.X).
- Platform: Java 8 and later.
- Who is exposed: servers or clients that use Bouncy Castle's DTLS stack, typically over UDP.
How to check if you're exposed
Find which Bouncy Castle artifacts and versions your build resolves, including indirect ones.
mvn dependency:tree -Dincludes=org.bouncycastle
./gradlew dependencies --configuration runtimeClasspath | grep -i bouncycastle
Look for artifacts such as bcprov, bcpkix, bcpg and bctls, and compare the version with the fixed versions above. Check shaded or fat jars and container images as well, because Bouncy Castle is often bundled inside other libraries and a copy can hide there.
Check whether you use DTLS from Bouncy Castle. Search for DTLSServerProtocol, DTLSClientProtocol and the bctls artifact in your dependency tree. Standard Java TLS from the JDK is a different implementation and is not covered by this advisory. Pay attention to anything that listens on a UDP port and terminates DTLS, such as IoT gateways, CoAP servers and WebRTC related services.
What to do now
- Upgrade to Bouncy Castle 1.85, LTS 2.73.12, or bctls-fips 1.0.24, 2.0.24 or 2.1.24.
- Rate limit UDP traffic to your DTLS listener and restrict it to expected networks where you can.
- Set a JVM heap limit and alert on OutOfMemoryError so a restart happens quickly.
- Add this listener to your inventory of internet facing Java services.
- Run the free in-browser dependency scan on your lockfile or manifest to see every affected package in one pass.
Why it matters
The weakness is CWE-789 (Memory Allocation with Excessive Size Value). According to the advisory, the DTLS handshake code reads a 24-bit length from each incoming record and builds a reassembler that immediately allocates that many bytes. The stream TLS path checks against a maximum handshake message size, but the DTLS path did not.
Up to 16 sequence numbers can be buffered per connection, so a single record of about 205 bytes with sixteen fragment headers claiming the maximum length forces roughly 256 MiB of allocation before any authentication. A handful of small UDP datagrams can then cause an OutOfMemoryError. The record scores it 7.5 (High) and does not mark it as exploited in the wild.
Quick check
Does the attacker need to authenticate?
No. The advisory says the allocation happens before authentication, and an unauthenticated remote attacker can trigger it with small UDP datagrams.
Sources
Last reviewed: 18 October 2026.