# Transaction dropped and replaced: meaning and fix

> Etherscan shows Dropped & Replaced when another transaction with the same nonce was mined. Who replaced it, was the fee paid, and what to do next.

Source: https://hashspan.dev/errors/transaction-dropped-and-replaced

## Short answer

Your transaction waited in the mempool, and another transaction from the same address with the same nonce was mined first. Only one transaction per sender and nonce can be mined, so yours never will be. Its fee was not paid. Look up the replacing transaction: if it was a speed-up or cancel you sent, nothing is wrong; if not, find what sent it and resend what you still need.

## What you will see

- `Dropped & Replaced`

## Where does it stop?

Figure: A transaction's path from your code to the node, the mempool, a block and a receipt. The mempool is marked in red with Dropped & Replaced: the transaction has a hash but never reaches a block or a receipt.

The node accepted your transaction and gave you a hash. It waited in the mempool, and then another transaction took its place. It will never reach a block.

## What happened to my transaction?

An account's transactions are numbered by nonce, and each number can be used once. Two transactions with the same sender and nonce can wait at the same time, but only one of them can be mined.

Figure: Transaction A with nonce 0 waits at a 2 gwei max fee. Transaction B with the same nonce, 0 ETH to the sender at 2.4 gwei, is mined in block 1 and succeeds. Transaction A is marked Dropped & Replaced: no receipt and no fee paid.

On [Etherscan](https://info.etherscan.com/dropped-and-replaced-meaning) the first one shows as "Dropped & Replaced". Its gas fee is not charged, because it was never mined.

## Who replaced it?

Open the replacing transaction: same sender, same nonce. What changed tells you why. viem uses the same three cases when it notices a replacement ([`onReplaced`](https://viem.sh/docs/actions/public/waitForTransactionReceipt)):

| viem `reason` | What changed | Usually |
|---|---|---|
| `repriced` | Only the fee | A speed-up |
| `cancelled` | Value is 0 | A cancel |
| `replaced` | Value or data | A different transaction |

`repriced` and `cancelled` are usually you or your wallet. `replaced` is the one to check: another process signed with the same key.

## Why does it happen?

- **You sped it up or cancelled it** in a wallet. This is the expected case.
- **A retry sent a new version** with a higher fee while the first was still waiting.
- **Two senders share one key.** Two workers or two agents each pick the next nonce and send. The second one replaces the first if it pays enough more; otherwise the node refuses it with [replacement transaction underpriced](https://hashspan.dev/errors/replacement-transaction-underpriced).

## What should I do?

1. **Check the replacing transaction's status.** If it succeeded and it was your speed-up or cancel, you're done.
2. **If you still need the original action, send it again** with the next nonce. The old one can't be revived.
3. **If you didn't expect a replacement, find the second sender.** Give each worker its own key, or let one place assign nonces.
4. **In code, handle the replacement instead of waiting forever:**

```ts

declare const publicClient: PublicClient;
declare const hash: Hash; // the transaction you are waiting for
const receipt = await publicClient.waitForTransactionReceipt({
  hash,
  onReplaced: ({ reason, replacedTransaction, transaction }) => {
    console.warn(`${replacedTransaction.hash} ${reason} by ${transaction.hash}`);
  },
});
// in our run (wait started first): receipt.transactionHash was the replacing transaction's hash
```

In our run, when the wait had read the first transaction before the cancel arrived, it resolved with the receipt of the transaction that replaced it. Check `receipt.transactionHash` before you treat it as yours.

## Why is my wait stuck after a replacement?

In our runs, viem spotted a replacement only when it had read your transaction before it was replaced. When the cancel went out right away, the wait never saw the original: it ran until viem's default `timeout` of 180 seconds and threw `WaitForTransactionReceiptTimeoutError`. With the cancel sent 500 ms later, the same wait resolved with the cancel's receipt.

So a wait that hangs after a speed-up or cancel may not be stuck on the chain. Look the nonce up instead: if `getTransactionCount` for the sender is past your nonce and your hash has no receipt, it was replaced. hashspan ends that confirm span with error status and `error.type` `timeout`.

## What does it look like in a trace?

hashspan ends the confirm span of the waited-for hash as `replaced`, with the hash that took its place. The receipt goes on the replacing transaction's own confirm span:

<AttributeCard
span="confirm 31337 · the original transaction"
rows={[
['blockchain.tx.status', 'replaced'],
['blockchain.tx.replacement.hash', 'the hash of the replacing transaction'],
]}
caption="From the run above. The replacing transaction's own confirm span has blockchain.tx.status success and the block."
/>

So the fee and the status are never put on the wrong hash. How a receipt is attributed is in the [transaction lifecycle](https://hashspan.dev/learn/tx-lifecycle).

## FAQ

### Did I pay gas for a dropped and replaced transaction?

No. It was never mined, so it has no receipt and no fee was charged for it. You paid only for the transaction that replaced it.

### Can a dropped and replaced transaction still go through?

No. The replacing transaction used its nonce, and a nonce can be used once. To do the same thing again, send a new transaction with the next nonce.

### Why did my transaction get replaced if I didn't do anything?

Something with access to the same key sent a transaction with the same nonce: a wallet's speed-up or cancel, a retry in your code, or a second process or agent that signs with the same key and picks its own nonce. Compare the replacing transaction's value and data with yours to see which.

### Why does waitForTransactionReceipt time out after a speed-up or cancel?

In our runs, viem detected a replacement only when it had read your transaction first. When the replacement came first, the wait could not connect the two and runs until its timeout, 180 seconds by default. Check the sender's nonce: if it moved past yours and your hash has no receipt, the transaction was replaced.

### What is the difference between dropped and replaced?

Dropped means nodes stopped keeping the transaction in their mempools, for example because its fee was too low. Replaced means another transaction took its nonce. Etherscan shows both words together when the nonce was then used by another transaction.
