Troubleshooting Transactions
Learn how to troubleshoot common problems with transactions on Paxeer Network
Common Issues
This guide helps you diagnose and fix common transaction problems on Paxeer Network.
Transaction Stuck in Mempool
Symptoms
- Transaction shows as "pending" for extended period
- Transaction doesn't get mined
- No confirmation after several minutes
Cause
The max fee per gas is too low compared to the current base fee.
Solution
Send a new transaction with the same nonce but higher fee:
import { ethers } from 'ethers';
async function replaceTransaction(originalTx, newMaxFee) {
const signer = await provider.getSigner();
// Get the nonce from the stuck transaction
const nonce = await originalTx.nonce;
// Send new transaction with same nonce, higher fee
const newTx = await signer.sendTransaction({
...originalTx,
nonce: nonce,
maxFeePerGas: newMaxFee, // Higher than before
maxPriorityFeePerGas: ethers.parseUnits('2', 'gwei'), // Higher priority
});
console.log('Replacement tx:', newTx.hash);
return await newTx.wait();
}Send a 0 value transaction to yourself with same nonce:
async function cancelTransaction(stuckTxNonce) {
const signer = await provider.getSigner();
const address = await signer.getAddress();
// Get current fee data
const feeData = await provider.getFeeData();
// Send 0 value to yourself with higher fee
const cancelTx = await signer.sendTransaction({
to: address,
value: 0,
nonce: stuckTxNonce,
maxFeePerGas: feeData.maxFeePerGas * 2n, // Much higher
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas * 2n,
gasLimit: 21000,
});
console.log('Cancel tx:', cancelTx.hash);
return await cancelTx.wait();
}When replacing or canceling a transaction, you must use the same nonce as the original transaction. The replacement must also have a higher gas price (typically 10%+ more).
Out of Gas Error
Symptoms
- Transaction reverts with "out of gas" error
- Transaction receipt shows
status: 0
Cause
The gas limit was set too low for the transaction's execution.
Solution
Re-estimate Gas
const gasEstimate = await provider.estimateGas(tx);
console.log('Required gas:', gasEstimate.toString());Add Sufficient Buffer
const gasLimit = gasEstimate * 150n / 100n; // 50% bufferCheck for Contract Issues
If gas estimates are extremely high:
- Contract may have infinite loops
- Contract may be poorly optimized
- Transaction may be calling expensive operations
Insufficient Funds
Symptoms
- Error: "insufficient funds for gas * price + value"
- Transaction rejected before sending
Cause
Account doesn't have enough PAX to cover: (gasLimit × maxFeePerGas) + value
Solution
async function checkSufficientBalance(tx) {
const signer = await provider.getSigner();
const address = await signer.getAddress();
// Get current balance
const balance = await provider.getBalance(address);
// Calculate required balance
const gasEstimate = await provider.estimateGas(tx);
const feeData = await provider.getFeeData();
const maxCost = gasEstimate * feeData.maxFeePerGas;
const totalRequired = maxCost + (tx.value || 0n);
console.log('Current balance:', ethers.formatEther(balance), 'PAX');
console.log('Required balance:', ethers.formatEther(totalRequired), 'PAX');
if (balance < totalRequired) {
throw new Error(`Insufficient funds. Need ${ethers.formatEther(totalRequired - balance)} more PAX`);
}
return true;
}
// Usage
await checkSufficientBalance(tx);Transaction Reverted
Symptoms
- Transaction mined but
status: 0(failed) - Receipt shows gas used but state didn't change
Cause
Contract execution failed due to:
- Failed
require()orassert()statement - Out of gas during execution
- External call failure
- Invalid operation
Debugging Steps
Check Transaction Receipt
const receipt = await provider.getTransactionReceipt(txHash);
if (receipt.status === 0) {
console.log('Transaction failed!');
console.log('Gas used:', receipt.gasUsed.toString());
console.log('Block:', receipt.blockNumber);
}Simulate Transaction
Use eth_call to simulate before sending:
try {
const result = await provider.call(tx);
console.log('Simulation successful:', result);
} catch (error) {
console.error('Simulation failed:', error.message);
// Don't send the transaction
}Check Logs and Events
const receipt = await provider.getTransactionReceipt(txHash);
receipt.logs.forEach(log => {
console.log('Event emitted:', log);
});Use Block Explorer
View detailed error messages on PaxeerScan:
https://paxscan.paxeer.app/tx/0x...Nonce Issues
Nonce Too Low
Error: "nonce too low"
Cause: Transaction uses a nonce that's already been used.
Solution:
// Get the correct nonce
const nonce = await provider.getTransactionCount(address, 'pending');Nonce Too High
Error: "nonce too high"
Cause: Transaction uses a nonce higher than expected (gap in nonces).
Solution:
// Always use the next available nonce
const nonce = await provider.getTransactionCount(address, 'latest');Nonce Management for Multiple Transactions
async function sendMultipleTransactions(transactions) {
const signer = await provider.getSigner();
let nonce = await provider.getTransactionCount(
await signer.getAddress(),
'pending'
);
const txPromises = transactions.map(async (tx, index) => {
const txResponse = await signer.sendTransaction({
...tx,
nonce: nonce + index,
});
return txResponse.wait();
});
return await Promise.all(txPromises);
}Gas Price Too Low
Symptoms
- Transaction not being picked up
- Sitting in mempool indefinitely
Solution
Set higher fees:
const feeData = await provider.getFeeData();
// Set max fee to 2x current
const maxFeePerGas = feeData.maxFeePerGas * 2n;
// Set priority fee for faster inclusion
const maxPriorityFeePerGas = ethers.parseUnits('2', 'gwei');RPC Error: Transaction Underpriced
Error Message
"transaction underpriced"Cause
Priority fee is too low for current network conditions.
Solution
// Get recommended priority fee
const recommendedPriority = await provider.send('eth_maxPriorityFeePerGas', []);
// Use at least the recommended amount
const tx = await signer.sendTransaction({
...txData,
maxPriorityFeePerGas: recommendedPriority,
});Transaction Takes Too Long
Normal Confirmation Times
| Priority | Expected Time | Block Count |
|---|---|---|
| Low (0 gwei) | 10-30 seconds | 5-15 blocks |
| Standard | 4-10 seconds | 2-5 blocks |
| High (2x priority) | 2-4 seconds | 1-2 blocks |
If Taking Longer
Check Transaction Status
const tx = await provider.getTransaction(txHash);
if (!tx) {
console.log('Not yet mined');
} else if (!tx.blockNumber) {
console.log('In mempool, waiting for block');
} else {
console.log('Mined in block:', tx.blockNumber);
}Check Network Status
Visit the network status page:
https://status.paxeer.appIncrease Priority Fee
If stuck, replace with higher priority fee (see above)
Contract Call Failures
Common Revert Reasons
Debugging Tools
Using Tenderly
Simulate and debug transactions:
// Use Tenderly's simulation API
const simulation = await fetch('https://api.tenderly.co/api/v1/account/me/project/my-project/simulate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Key': 'YOUR_KEY',
},
body: JSON.stringify({
network_id: '125',
from: fromAddress,
to: toAddress,
input: data,
value: value.toString(),
}),
});
const result = await simulation.json();
console.log('Simulation result:', result);Using PaxeerScan
Check transaction details and error messages:
- Go to https://paxscan.paxeer.app
- Search for your transaction hash
- View execution trace and error messages
- Check event logs for clues
Prevention Checklist
Before sending transactions:
- Estimate gas with
eth_estimateGas - Add 10-20% buffer to gas estimate
- Check current base fee is reasonable
- Set appropriate priority fee
- Verify account has sufficient balance
- Simulate transaction with
eth_callfirst - Validate all input parameters
- Handle errors gracefully in code
Getting Help
Discord Community
Ask questions and get help
GitHub Issues
Report bugs and issues
Block Explorer
Investigate transactions
Status Page
Check network status
Next Steps
How is this guide?