Write-up published
Resolved
Summary
On Jan 12th, 2026, the Polygon PoS Mainnet experienced a delay in block finalization starting at approximately 16.00 UTC, caused by repeated proposal rejections at the consensus layer.
The incident was triggered by a deterministic mismatch between PrepareProposal and ProcessProposal logic in Heimdall, leading validators to reject otherwise valid block proposals due to an account sequence inconsistency. Finalization resumed after the offending logic was removed and validators converged on a consistent proposal execution path.
Impact
No new blocks in bor chain were finalised during the incident window.
User transactions were delayed
What happened
A block proposer constructed a proposal containing a valid transaction from an account that had previously submitted an invalid transaction.
The invalid transaction was skipped during PrepareProposal and never included in the proposal, due to a bug.
The subsequent valid transaction \(from the same sender\) was included, but had a higher account sequence number.
During ProcessProposal, validators attempted to execute the included transaction in isolation, without having applied the skipped transaction.
This caused an account sequence mismatch, leading validators to deterministically reject the proposal.
Repeated proposal rejections prevented consensus from progressing, resulting in a heimdall consensus error.
Root cause
Execution of message handlers during ProcessProposal introduced an invalid assumption about account sequence progression.
Specifically:
In Cosmos SDK, each transaction from an account must have a contiguous sequence number.
PrepareProposal is allowed to skip invalid transactions when constructing a proposal.
ProcessProposal, however, must not assume that skipped transactions were executed.
A recently introduced call to execMsgHandler in ProcessProposal attempted to execute message handlers against a cached state context.
When multiple transactions from the same sender were involved:
If an earlier transaction \(sequence x\) was skipped in PrepareProposal,
and a later transaction \(sequence x+1\) was included,
ProcessProposal would reject the proposal due to a sequence mismatch.
This violated the fundamental Cosmos SDK invariant that state transitions \(including sequence increments\) must only occur during block execution, not proposal validation.
The issue was fully deterministic and reproducible under these conditions.
This was not caught earlier because:
The logic was introduced as part of security hardening, to perform additional validation during ProcessProposal.
The failure mode only manifests when:
Multiple transactions from the same sender are present in the mempool, and
An earlier transaction is invalid but a later one is valid.
This edge case was not covered by existing proposal-level tests.
Resolution and recovery
All validators were called to rollback to the previous working version of heimdall, where the offending logic \(execMsgHandler\) was removed from ProcessProposal.
Once validators processed proposals under consistent logic, consensus resumed and blocks finalization in bor recovered automatically.
Resolved
This incident has been resolved.
Monitoring
Finality has caught up and is back to normal on Polygon. We’ll continue monitoring the network closely and will share updates if anything changes.
Monitoring
A fix has been implemented and we are monitoring the results.
Investigating
Polygon is currently seeing a temporary network delay in block finality. Our team is actively investigating the cause and coordinating to restore full functionality. Thank you for your patience!