Nonce Increment Gaps After web3js Pending Transaction Drop
0 reputation · 31 Oct 2020, 01:53 UTC
0 reputation · 31 Oct 2020, 01:53 UTC
When a web3js sendTransaction remains pending, the library does not automatically increment the sender's nonce on retry. The precise goal is to identify a retry pattern that guarantees write-idempotency for signed transactions without requiring the developer to manually maintain a nonce counter that survives mempool eviction and chain reorganization.
If the original transaction mines successfully and a resend reuses the same nonce, the network rejects the duplicate, preventing unintended writes. However, if the pending transaction is dropped from the mempool before mining, the nonce does not advance, leaving a gap that subsequent transactions must offset. This gap can cause sequence errors or, if the developer resends without incrementing, silently duplicate the write once the original eventually confirms. EIP-1559's maxFeePerGas and maxPriorityFeePerGas do not influence nonce behavior, leaving retry safety dependent solely on nonce management.
How should a developer detect mempool eviction before resending? What nonce value should be used if the original transaction's status remains ambiguous? Can transaction receipt polling reliably prevent duplicate writes in all network conditions?
35275 reputation · 31 Oct 2020, 04:04 UTC
Detect mempool eviction with a heuristic, not an on-chain event. Use nonce = max(confirmed nonce + 1, highest still-visible pending nonce for the sender). Receipt polling alone cannot guarantee duplicate prevention under reorgs or node-specific mempool views.
Silent duplicate writes arise only when a developer increments the nonce on retry while the original is still pending and later mines. Keeping nonce stable for retries and only advancing after confirmed inclusion preserves write idempotency. Node mempool views differ by provider and region, so a tx absent on one RPC may still be pending elsewhere. Chain reorganizations can make a receipt appear then disappear.
Receipt polling is not sufficient alone for all network conditions. Treat a receipt as final only after sufficient confirmations for your target security level.
Are you sending raw signed transactions off-chain where you control nonce persistence, or using web3.eth.sendTransaction with the provider managing nonce? The recommendation for durable storage differs.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.