github besu-eth/besu 26.10.2

3 hours ago

Security Updates

Docker images no longer trust the eMudhra roots listed in OpenJDK's guidance after the October 2026 CA compromise

  • emSign ECC Root CA - G3 (related to the compromised intermediate certificate authorities)
  • emSign Root CA - G1 (a precaution), along with
  • emSign Root CA - G2 and AAA Certificate Services

This removal applies only to the Docker images; if you run the Besu archive (tar/zip) on your own distribution or vendor JDK, that JDK may still trust these roots — see the eMudhra incident report to check and remediate it. #11756

Breaking Changes

  • eth_getProof now rejects a request with more than 1024 storage keys with Invalid storage keys params (-32602), the same limit as geth, Nethermind and Erigon. #11697
  • eth_call, eth_estimateGas, eth_createAccessList, trace_call and trace_callMany now reject a call that sets maxFeePerBlobGas without blob versioned hashes, or that sets an empty blobVersionedHashes list, with Invalid blob count (-32602) at every fork. Previously a maxFeePerBlobGas without hashes was accepted and the call ran without blobs, and a maxFeePerBlobGas of 0 also set the blob base fee the call saw to 0. An empty list failed with Internal error (-32603). Each call in a trace_callMany bundle gets the same rule. debug_traceCall and eth_simulateV1 reject only an empty blobVersionedHashes list, and still accept a maxFeePerBlobGas without hashes. #11556
  • trace_filter now matches a block reward's author against toAddress in range queries, as it already did for a single block, so a filter on an author's address returns its reward traces. #11436

Bug fixes

  • The Osaka (EIP-7883) MODEXP gas cost now saturates for declared base or modulus lengths of 2^34 - 7 bytes and above, matching go-ethereum and reth. The multiplication complexity overflowed and the price fell to the 500 gas floor. Mainnet is unaffected because EIP-7823 caps those lengths at 1024 bytes. #11596
  • The layered transaction pool no longer logs an IndexOutOfBoundsException when a sender's pending transactions are reconciled against an account nonce that leaves them --tx-pool-max-future-by-sender or more nonces ahead, as on a node that has fallen behind the chain head. Those transactions are now dropped during the reconciliation, as a new transaction that far ahead would be. #11501
  • eth_simulateV1 now numbers logIndex over the logs that the calls of a block return, starting at 0, as execution-apis specifies. Previously each call that returned no logs, such as a failed call, still used one index. #11584
  • Fix incorrect sync status reporting. eth_syncing now reports progress during snap sync (previously it reported "not syncing" for the whole snap sync), with highestBlock taken from the best-chain height (the latest engine_newPayload head under PoS). The ethstats syncing field and BackwardSyncContext.isSyncing() no longer report the inverse of the actual state. /readiness no longer reports ready while the world state download, trie heal or flat database heal is still in progress. A backward sync session that completed synchronously is no longer reused by later calls. #11260
  • eth_simulateV1 with validation disabled now returns -32603 for a call whose sender nonce is 2^64-1, as EIP-2681 requires. Previously the nonce wrapped to 0 and the call succeeded. A call whose nonce is below the sender nonce now runs instead of failing with -38010, because disabled validation skips the check that the call nonce equals the sender nonce. #11578
  • eth_simulateV1 with validation disabled no longer caps the execution gas of a call after Amsterdam at TX_MAX_GAS_LIMIT (EIP-8037). The whole gas limit of the call is execution gas, and the default gas limit is the block gas limit minus the larger of the execution gas and the state gas that the block has used. With validation enabled, a call whose intrinsic or calldata floor cost exceeds TX_MAX_GAS_LIMIT is now rejected with -38013, because EIP-8037 caps that cost. Geth rejects the same call with -32603. #11579
  • evmtool t8n now reports a failure while processing execution layer requests, such as a malformed deposit event, as blockException in its result, like block import rejects the block. It previously failed the whole transition, so t8n-server answered with HTTP 500. #11570
  • --ethstats connections no longer drop at the next garbage collection, a regression since 26.8.1. #11589
  • --ethstats no longer retains a few KB of heap per reconnect attempt while the ethstats server is unreachable. #11614
  • debug_traceBlockByNumber now returns BLOCK_NOT_FOUND for a block number beyond the chain head, as debug_traceBlockByHash does for an unknown hash. Previously it returned a null result. #11437
  • trace_callMany accepts a call without its block argument and runs the bundle at latest, as trace_call does. Previously a request with only the calls was rejected with Invalid number of params (-32602). #11440
  • PipelineBuilder.inBatches now rejects a non-positive maximum batch size when a custom stop condition is used, matching the overload without a stop condition. #11479
  • newPendingTransactions subscriptions with full transactions now include blockHash, blockNumber, transactionIndex and blockTimestamp as null, as eth_getTransactionByHash and the txpool methods return them for a pending transaction. #11427
  • Fix JSON-RPC active-connection counter leaks on the Engine API, HTTP, and WebSocket services. Rejected connections no longer increment the count or register a close handler; abrupt WebSocket disconnects (including TCP RST mid-response) now release the counter exactly once; rejection logs print {current}/{max}; and the Engine API exposes besu_rpc_active_engine_connection_count like the existing HTTP/WS gauges. Without this, counters could climb until --rpc-*-max-active-connections blocked all new clients (including a consensus client on the Engine API). #11453
  • RocksDB is now closed on shutdown. KeyValueStorageProvider.close() filtered its Map.Entry elements by instanceof AutoCloseable, which is always false, so no storage instance was ever closed and every restart replayed the RocksDB WAL. #11390
  • eth_getLogs and GraphQL logs now enforce the --rpc-max-log-filter-addresses cap on the address list that eth_newFilter and eth_subscribe already applied, closing that bypass of the fix for GHSA-p6f8-q9mp-7mj9. A request naming more addresses than the cap is rejected before any block is read: JSON-RPC returns Filter address count exceeds limit (-32005) and GraphQL returns Invalid params. The default stays 1000 addresses; --rpc-max-log-filter-addresses=0 keeps the previous uncapped behaviour. #11667
  • Debug traces with an opcode filter or a step limit report the post-execution gas of the last recorded operation; every later operation overwrote it. #11524
  • The PAY opcode (EIP-5920, future EIPs fork only) pays from the current address instead of the caller. #11544
  • A peer that answers a header, body or sync block body request with malformed RLP is now disconnected for breach of protocol, as it already was for pooled transactions, receipts and block access lists. Previously the decoding failure was logged at ERROR as a server error and the peer stayed connected. #11451
  • The layered transaction pool notifies a transaction as added before the evictions that make space for it. Previously, when the pool was full after adding a transaction and the eviction dropped the transaction itself, it was notified as dropped before it was notified as added. #11688
  • The sequenced transaction pool notifies transaction added and dropped events in the order they happen. Previously a transaction could be notified as dropped before it was notified as added, when another thread replaced it right after it was added, or when it was evicted because the pool was full after adding it. A transaction removed by the timed eviction after it had already been dropped is no longer notified as dropped a second time. #11685

Additions and Improvements

  • trace_filter accepts mode: intersection, the default, or union, which matches a trace in either fromAddress or toAddress. An unknown value is rejected with -32602. #11436
  • EVM v2 (--Xevm-v2) runs every opcode on its own stack and supports tracers. #11524
  • EVM v2: add DUP1-16 and SWAP1-16. #11482
  • Bound the cost of jump destination analysis on code crafted to slow it down. #11400
  • --rpc-http-max-active-connections and --rpc-ws-max-active-connections accept 0 as unlimited (same convention as --rpc-ws-max-active-subscriptions). Negative values are rejected. #11453
  • Block building checks the block access list item budget of each transaction without copying the whole list. #11454
  • Debug traces with a step limit no longer take snapshots of the operations past the limit, which made a limited trace of a long transaction as slow as a full one. #11524
  • OperationTracer.tracesOperations() lets a tracer that only uses transaction or call hooks skip the per-operation calls on EVM v2. #11524
  • Tracers read the stack of a frame through TracedStack, which also reads the EVM v2 stack. With --Xevm-v2, a plugin tracer that calls MessageFrame.getStackItem or stackSize throws a NullPointerException, as those read only the EVM v1 stack. #11524
  • Snap sync checks the flat database ranges of its heal stage in parallel, which shortens that stage on mainnet from about 3 h 40 min to 34 min. #11495
  • Update the discovery library to 26.10.1 for faster discv5 secp256k1 verification and ECDH, with Netty, BouncyCastle, Guava, Log4j and Reactor raised to the versions it requires. #11671
  • Unschedule the Amsterdam fork on Hoodi, which 26.10.0 scheduled at timestamp 1793036568. #11709

20a1fc58828bf1e2f06c7a2addcde2b7be10e7c09d0f623944f278857fd4ff43 besu-26.10.2.zip
8cc633e19cb23cd38b5d6ad988b725c8533389a773aea65782fd16d37946825b besu-26.10.2.tar.gz

New Contributors

Full Changelog: 26.10.0...26.10.2

Don't miss a new besu release

NewReleases is sending notifications on new releases.