This release contains security fixes. Operators are advised to upgrade promptly.
Details will be published in security advisories on
https://github.com/besu-eth/besu/security/advisories after operators have had an
opportunity to upgrade.
Breaking Changes
BlockSimulationParameter.Builder.enforceConsensusGasLimitCaps()is renamed toenforceConsensusGasLimit(). The flag now also controls whether the EIP-1559 gas limit adjustment algorithm is applied: whentrue(plugin/block-production path)getNextGasLimit()is used; whenfalse(default,eth_simulateV1path) the parent gas limit is inherited unchanged, matching geth and Nethermind. #11254BlockResultconstructor signatures no longer accept atotalDifficultyparameter. The field was already ignored (alwaysnullpost-merge). Any code constructingBlockResultdirectly must drop theDifficultyargument. #11179debug_traceCallnow applies the same balance-check rules aseth_call#11230eth_feeHistorynow rejects reward percentiles outside[0, 100], not strictly increasing, or more than 100 values (-32602), instead of sorting unordered input or silently omittingrewardfor oversize lists. #11055- Removed the EIP-7610 storage collision check: contract creation no longer aborts when the destination address has non-empty storage but a zero nonce and no code, restoring the EIP-684 conditions for every fork. EIP-7610 was declined for inclusion in Glamsterdam (EIP-7773) and removed from the execution specs retroactively; no mainnet account is affected.
Account.isStorageEmpty(), which existed only for this check, is removed from thebesu-evmAPI. #11175 - Besu now exits on
OutOfMemoryError(-XX:+ExitOnOutOfMemoryError). Use a restart policy, or setJAVA_OPTS=-XX:-ExitOnOutOfMemoryErrorto opt out. #11300
Upcoming Breaking Changes
- Plugin API
PluginTransactionSelectorFactory.create(final SelectorsStateManager selectorsStateManager)is deprecated for removalPoaQueryServiceandBftQueryServiceare deprecated and will be removed in a future release, with no replacement. They have no known usageMiningServiceis deprecated for removal and will be removed in a future release, with no replacement. It has no known usageBesuEventsis deprecated and will be removed at the breaking release. Its event families are available onBlockchainService,TransactionPoolServiceandSynchronizationServicethroughsubscribe*methods returning aSubscriptionhandle;TTDReachedListenerhas no replacement, since it never had an add method. #11283- The plugin API is being reorganized into per-feature modules (#10820). Nothing has changed for plugin authors yet:
besu-plugin-apire-exports every module, so existing plugins compile and run unmodified. A future release will apply the breaking changes, batched into a single break with a migration guide:- packages are renamed to match their module, for example
org.hyperledger.besu.plugin.services.storagebecomesorg.hyperledger.besu.plugin.storage, with contracts plugins implement moving under anspisub-package - contracts that serve several unrelated audiences are split apart, and contracts that overlap are merged into one
- types and methods whose names no longer describe what they do are renamed, and a number of signatures change
- contracts and methods that are deprecated, superseded, or have no known usage are removed
- packages are renamed to match their module, for example
- The plugin lifecycle is being redesigned. The phases a plugin goes through, the services available in each of them, and the way a plugin obtains those services are all expected to change, and the changes will not be source compatible.
PluginVersionsProvider,plugin.data.Request,plugin.data.Restriction,plugin.data.UnsignedPrivateMarkerTransactionandplugin.data.Signatureare deprecated for removal, with no replacement. None is reachable through any plugin service or data contract: the three privacy types were orphaned when private transaction support was removed,Requestis implemented internally but never exposed, andPluginVersionsProvideris internal--versionplumbing
--Xbft-legacy-protocol-encodingwill be removed once Besu 25.x is no longer supported. #10499--Xsnapsync-synchronizer-pivot-block-distance-before-cachingis deprecated (since 26.6.1) and will be removed in a future release; the flag is now a silent no-op.--snapsync-synchronizer-pre-checkpoint-headers-only-enabledis deprecated (since 26.8.1) and will be removed in a future release; the flag is now a silent no-op.--rpc-tx-feecapwill treat a value of 0 as limiting fees to 0. Today it treats 0 as "do not cap fees". To achieve similar behaviour set it to a suitably large value to effectively prevent any fee capping.
Bug fixes
BesuEvents.removeBlockReorgListenernow unsubscribes the reorg listener it was given. It calledBlockchain.removeObserver, which only searches the block-added observer list, so the plugin's reorg listener kept firing after removal and, because the two lists number their ids independently from zero, the call could instead remove an unrelated block-added observer holding the same id, including one of Besu's own. It now callsremoveChainReorgObserver. #11283eth_simulateV1simulated blocks now inherit the parent block'sgasLimitunchanged when nogasLimitoverride is provided, matching the execution-apis spec and the behaviour of geth and Nethermind. PreviouslyBlockSimulatorapplied the EIP-1559 adjustment algorithm toward the node'stargetGasLimit, causing simulated results to diverge from expected values when the parent's gas limit differed from the target (e.g. 200M on Amsterdam hive fixtures). #11254- Reject malformed RLPx ECIES handshake payloads under 32 bytes cleanly with
InvalidCipherTextExceptioninstead of raising an unhandledNegativeArraySizeException. #11218 - GraphQL
logs(filter: ...)no longer fails when the filter'stopicsfield is omitted or explicitly null, on both the top-levellogsquery and the block-scoped one. The schema declarestopicsnullable and documents "[] or nil matches any topic list", but the field was dereferenced unguarded, so a documented-valid query returned aDataFetchingExceptionanddata: null. #11188 - The Engine API JWT fast-path cache now compares the presented bearer token against the cached one with
MessageDigest.isEqualover UTF-8 bytes instead ofString.equals, so the comparison does not return early on the first differing byte. - Fix ENR fork ID not updating after timestamp-scheduled forks when no block lands exactly on the fork timestamp. #10882
- Besu no longer announces the EIP-4844 version 0 size of a blob transaction while serving the EIP-7594 version 1 (cell proofs) encoding. From Osaka on, a locally submitted version 0 blob transaction is upgraded to version 1 before it is pooled, but the pre-upgrade transaction was the one broadcast, so
NewPooledTransactionHashesunder-announced it by 6,226 bytes per blob against whatGetPooledTransactionsthen served, and go-ethereum peers responded withdropPeer(). #11203 admin_logsRemoveCacheno longer reportsCache Removedwhen nothing was removed.TransactionLogBloomCacher.removeSegmentsskips the whole deletion while log bloom caching is in progress, so the RPC returned success while every cache file was still on disk. It now returns an error in that case. #11080- Fix
eth_getProofreturning an empty storageProof array for non-existent accounts regardless of requested keys. EIP-1186 requires one entry per requested key #11082 - Serialize
BftMiningCoordinatorenable()/disable()withstart()/stop()so the mining state flips and their surrounding checks can no longer interleave with concurrent lifecycle transitions. #10887 - An EIP-7702 transaction with an empty
authorization_listis now rejected by transaction validation rather than by RLP decoding. Over the Engine API such a transaction made the whole payload reportFailed to decode transactions from block parameter, hiding both the rule that was broken and any other defect the transaction had. #11193 engine_newPayloadV4+ now returns-32602for anexecutionRequestselement consisting only of a type byte, as execution-apis requires, including when that type byte is one Besu does not recognize. Such an element was previously answered with anINVALIDpayload status. #11194- A block carrying a transaction whose gas limit exceeds the block's is now rejected for that, rather than reported as an EIP-7928 block access list failure. The access list item budget is checked before the block runs, so it pre-empted the gas error. #11195
engine_forkchoiceUpdatednow returns an internal error instead ofINVALIDwithlatestValidHashset to the head when a valid head cannot be applied locally. #11317engine_newPayloadandengine_forkchoiceUpdatednow returnINVALIDinstead ofSYNCINGfor a block whose parent is a known bad block. #11313- Fix performance regression with TLOAD/TSTORE caused by wrong backing implementation of transient storage. #11319
- Avoid RLPx connection attempts to discovery-only bootnodes with listening port
0(and to ENRs without atcp/tcp6field); they serve discovery only and stay bonded for FINDNODE.
Additions and Improvements
- Plugin API: the
BesuEventsevent families move onto the feature services that own them.BlockchainServicegainssubscribeBlockPropagated,subscribeBlockAdded,subscribeBlockReorg,subscribeLogsandsubscribeBadBlock;TransactionPoolServicegainssubscribeTransactionAddedandsubscribeTransactionDropped;SynchronizationServicegainssubscribeSyncStatusandsubscribeInitialSyncCompletion. Each returns aSubscriptionwhoseclose()unsubscribes that one listener, replacing thelongid and pairedremove*method, so an id can no longer be handed to the wrong family's remover, and initial sync completion becomes unsubscribable for the first time. The listener interfaces keep their signatures and move out ofBesuEventsinto anspipackage in each module.BesuEventskeeps working unchanged and is deprecated. #11283 - Implement native
callTracerexecution tracing, reducing memory use fordebug_trace*. #11077 - Implement native
4byteTracerexecution tracing, reducing memory use fordebug_trace*. #11271 - Add
flatCallTracerfordebug_trace*methods, matching geth output. #11273 - Implement native
prestateTracerexecution tracing, reducing memory use fordebug_trace*. #11289 - Upgrade the stable reference tests to
tests@v20.0.2, now published from theethereum/execution-specsrepository. #11175 eth_simulatenow returns EIP-7708 transfer logs for Amsterdam #11154- Tune layered txpool for upcoming Amsterdam 200M gas limit #11335
- Schedule the Amsterdam fork on Sepolia at timestamp
1791294816(Tue, 06 Oct 2026, 13:53:36 UTC). #11333
749f90b0b29b8138f5d58b949d19eed721826cab66bfb8d983f86e15831d22b2 besu-26.9.0.zip
172b29069837f13436a20bd7c8234aeca67917d8a378e81e2bd4a205c57540ea besu-26.9.0.tar.gz