October 2025 Post-mortem
Post-mortem: Aggregate Transaction Hash Collision Vulnerability (October 2025)
A vulnerability affecting aggregate transactions was recently identified and fixed in the Symbol network.
The issue could, under specific conditions, cause two distinct aggregate transactions to produce the same transaction hash.
A fix was deployed before any exploitation occurred.
Timeline
7 September, 02:30 AM UTC
The issue was first brought to the team’s attention when @daoka informed that Maitsuki-san had reported it on X.
25 September, 11:39 PM UTC
The hard fork activating the fix occurred at block height 4,759,100.
Background
Aggregate transactions in Symbol group multiple inner transactions into a single, atomic operation.
Each aggregate’s hash is derived from a Merkle tree built from its inner transactions.
The issue, discovered by a community contributor and confirmed by the core development team, stemmed from how incomplete Merkle trees are constructed when the number of embedded transactions is not a power of two.
In such cases, the hashing algorithm duplicates the final leaf to complete the tree. These duplicated leaves are only used to complete the Merkle tree structure and do not correspond to active transactions.
But this means that a transaction could be built by copying such an implicitly-filled aggregate, and adding duplicated, active, copies of the last transaction. This transaction would have the same Merkle hash, and therefore the same transaction hash as an already-signed transaction.
In practice, if account A sent funds to account B in the last embedded transaction of an aggregate, B could theoretically craft a new aggregate duplicating that same transfer multiple times, reusing A’s signature, because the resulting hashes would match. This would cause a network split that would eventually resolve to one of the two versions of the aggregate.
Corruption of past transactions is impossible due to the state hash.
Resolution
To eliminate this vulnerability, Aggregate Transaction Version 3 includes the total payload size (in bytes) of all embedded transactions, which was already part of the transaction header, in the aggregate hash computation.
This ensures that even structurally similar aggregates with duplicated embedded transactions now always produce distinct hashes.
The update was released as part of a scheduled hard fork.
Prior to the fork height, only version 2 aggregates were valid; from that block onward, only version 3 aggregates are accepted.
The majority of harvesting and voting nodes upgraded before activation, ensuring a smooth transition with no disruption to block production or finalization.
⚠️
All applications still using Aggregate V2 transactions have stopped working.
Nodes running the updated software now reject V2 aggregates, so affected apps must update to the latest SDK to emit Aggregate V3 transactions.
Impact Analysis
A retrospective analysis confirmed that no known transactions exploited this behavior.
Moreover, no instances of stolen funds have been reported.
Looking Ahead
We would like to thank Maitsuki-san who originally reported the issue, and all node operators who upgraded promptly to maintain network security and stability.
For further technical details, refer to the Symbol GitHub repository and the release notes for the aggregate v3 upgrade.