Skip to content

How to Fix MetaMask Pending Transactions

DodaTech Updated 2026-06-24 4 min read

In this tutorial, you'll learn about How to Fix MetaMask Pending Transactions. We cover key concepts, practical examples, and best practices.

The Problem

Your MetaMask transaction is stuck in "Pending" status for hours. The Activity tab shows a spinning icon, and subsequent transactions also hang because they use the same nonce. The transaction cannot be cancelled or sped up properly.

Quick Fix

Fix 1: Speed Up the Transaction

WRONG — clicking "Speed Up" without raising gas enough:

# (MetaMask suggests a small gas increase, but if the network is congested,
#  even the increased gas may not be enough)

RIGHT — manually set a high gas price when speeding up:

# 1. In MetaMask, click on the pending transaction
# 2. Click "Speed Up"
# 3. Click "Edit" next to gas price
# 4. Set gas price to at least 2x the current base fee + priority fee
# 5. Confirm

Fix 2: Cancel the Transaction

# 1. In MetaMask, click the pending transaction
# 2. Click "Cancel"
# 3. Confirm the cancellation
# (this sends a 0 ETH transaction with the same nonce and higher gas)

If MetaMask's cancel does not work, do it manually:

// Using ethers.js:
const tx = {
    to: "0x0000000000000000000000000000000000000000",
    value: 0,
    nonce: stuckNonce,  // same nonce as the stuck transaction
    gasLimit: 21000,
    maxPriorityFeePerGas: ethers.parseUnits("50", "gwei"),
    maxFeePerGas: ethers.parseUnits("100", "gwei"),
};
const replacementTx = await signer.sendTransaction(tx);
await replacementTx.wait();
// (this replaces the stuck transaction)

Fix 3: Clear Pending Transactions in MetaMask

If the transaction is stuck client-side:

# MetaMask Settings → Advanced → Clear activity tab data
# This clears the local transaction history (does not affect the blockchain)
# The transaction may still be pending on-chain

Fix 4: Use the Nonce Directly

// Get the current nonce from an external block explorer:
// etherscan.io/address/YOUR_ADDRESS → check "Nonce" tab

// In ethers.js, manually set the nonce:
const currentNonce = await provider.getTransactionCount(signer.address);
const tx = await signer.sendTransaction({
    to: "0x...",
    value: ethers.parseEther("0.1"),
    nonce: currentNonce,  // use the latest nonce
    gasLimit: 21000,
});

Fix 5: Transaction Replacement Underpriced

// Error: "replacement transaction underpriced"
// (the gas price on the replacement is not high enough)

Reference: the replacement must pay at least 10% more gas than the stuck transaction.

const stuckTx = await provider.getTransaction(stuckTxHash);
const minGasPrice = stuckTx.gasPrice * 110n / 100n;  // 10% more
const replacement = await signer.sendTransaction({
    to: "0x0000000000000000000000000000000000000000",
    value: 0,
    nonce: stuckTx.nonce,
    gasPrice: minGasPrice,
    gasLimit: 21000,
});

Fix 6: Nonce Pool Too Low (Out of Order)

// Transaction with nonce 5 is stuck → nonce 6 and 7 also cannot proceed
// (Ethereum processes transactions in nonce order)

Fix all pending nonces by replacing each stuck one.

// Cancel all transactions from nonce startNonce to currentNonce:
for (let nonce = startNonce; nonce < currentNonce; nonce++) {
    const pendingTx = await provider.getTransaction(signer.address, nonce);
    if (pendingTx && pendingTx.blockNumber === null) {
        // Send a 0 ETH replacement with higher gas
        await signer.sendTransaction({
            to: "0x0000000000000000000000000000000000000000",
            value: 0,
            nonce: nonce,
            gasPrice: pendingTx.gasPrice * 120n / 100n,
            gasLimit: 21000,
        });
    }
}

Use DodaTech's Transaction Monitor to track pending transactions, receive alerts when gas is too low, and automatically replace stuck transactions.

Prevention

  • Set realistic gas prices using eth_feeHistory or gas oracles.
  • Do not send multiple transactions from the same account simultaneously.
  • Always check the current base fee before sending.
  • Use maxPriorityFeePerGas and maxFeePerGas (EIP-1559) instead of gasPrice.
  • Keep a small ETH buffer for replacing stuck transactions.

Common Mistakes with pending tx

  1. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  2. Using head and tail instead of pattern matching, causing runtime errors on empty lists
  3. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks

These mistakes appear frequently in real-world METAMASK code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Why is my MetaMask transaction pending for hours?

The gas price you set is too low for the current network conditions. Miners prioritize transactions with higher gas prices. Either speed up the transaction with higher gas or wait for the network to clear. Transactions do not expire on Ethereum unless the network is restarted.

Can I cancel a transaction that is already pending?

Yes, send a 0 ETH transaction to your own address with the same nonce and a gas price at least 10% higher than the original. This replaces the pending transaction. MetaMask provides a "Cancel" button that does this automatically.

What happens if I restart MetaMask while a transaction is pending?

The transaction remains in the mempool and is still valid. MetaMask will re-sync the pending status when it reconnects. The transaction does not disappear or get cancelled by restarting MetaMask or your browser.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro