ByAUJay
Stuck pending on L1/L2 is rarely “just a gas issue.” It’s almost always a mix of nonce gaps, mempool policy, provider limits, and fee miscalculation under EIP‑1559 and post‑Dencun L2 economics. Below is a pragmatic runbook we use to unstick pipelines without blowing up budgets or SOC 2 audit trails.
Fixing “Stuck” Transactions: A Developer’s Troubleshooting Guide
Target audience: Enterprise product and platform teams shipping EVM-based wallets, payment rails, or tokenized flows, with SOC 2 and procurement constraints.
Pain — the specific headache engineering leaders report
- Your EOA or smart account has a transaction “Pending” for hours. You try to speed-up, get “replacement transaction underpriced,” and your queue is now blocked by a nonce gap. Meanwhile, your RPC returns “tx fee exceeds the configured cap (1.00 ether),” your L2 sequencer’s status page looks green but users keep filing tickets, and ops is asking why the cancel TX never propagated. Deadlines slip; SLAs wobble; finance asks about the rising support burden.
- Root causes are multi-variant:
- EIP‑1559 fee math not accounting for worst-case baseFee growth over the next N blocks, plus insufficient tip. Base fee adjusts up to 12.5% per block; variable block sizes mean you must plan for elasticity. (eips.ethereum.org)
- Client mempool policy: to replace a same‑nonce TX, major clients (e.g., Geth) require a price bump (default 10%) and reject underpriced replacements; non-executable TXs and queue entries age out (default ~3h). (geth.ethereum.org)
- RPC provider limits: tx fee caps (rpc.txfeecap default 1 ETH) and gas caps silently block “speed-up” attempts, surfacing confusing generic -32000 errors. (newreleases.io)
- Private orderflow quirks: private submissions (Flashbots Protect, bloXroute) won’t hit the public mempool unless you explicitly allow fallback or after a TTL (e.g., ~25 blocks for Protect). Cancellations may be made public immediately. (docs.flashbots.net)
- L2 specifics: after Dencun, blob-fee dynamics lowered L2 costs, but sequencer policies/timeouts and L1 data posting can still stall inclusion; some networks impose per-tx gas caps or block-based drop rules. (coinmarketcap.com)
- AA (ERC‑4337) paths: bundlers maintain a separate mempool; replacement requires bumping both maxPriorityFeePerGas and maxFeePerGas for the same sender+nonce. (eips-wg.github.io)
Agitation — why this is risky to ignore
- Missed launch dates and SLA violations: blocked nonces cascade—one underpriced TX prevents payroll, payouts, or mint flows behind it from even entering the mempool. Your “retry” loop hammers the same invalid TX for hours, then nodes drop it due to pool lifetimes. (etclabscore.github.io)
- Overspend and audit friction: “panic” gas bumps can hit RPC caps and trigger failed speed-ups; inconsistent fee logic makes spend unpredictable, complicating procurement forecasts and SOC 2 change-management evidence. (newreleases.io)
- L2 false confidence: post‑Dencun blob fees cut L2 cost dramatically, but sequencer behaviors (timeouts, censorship windows, or outages) still cause opaque stalls; some paths need explicit “force-inclusion” via L1 contracts after delays. (onchainstandard.com)
- Reputation costs: stalled treasury ops and consumer UX regressions spike support tickets. Private routing without mempool fallback loses access to ~10% of blocks where validators don’t run MEV‑Boost unless configured. (docs.flashbots.net)
Solution — 7Block Labs’ playbook for getting you back to green
We approach “stuck TX” remediation as an engineering system—fee policy, nonce discipline, mempool visibility, and provider strategy—implemented with testable runbooks and SOC 2‑friendly controls.
- Reproduce and observe (without guessing)
- Always compare nonces across states:
- eth_getTransactionCount(address, "latest") vs "pending" to see what the chain finalized vs your pending intent. “Pending” includes the local mempool view. (docs.chainstack.com)
- If you control a node, use txpool:
- txpool.status and txpool.content to see per-address queues, including multiple same‑nonce TXs. Not available on many hosted providers—plan for your own observability. (geth.ethereum.org)
- Check provider caps and policies:
- tx fee cap, gas cap, price bump thresholds, and pool lifetimes. Defaults often are txfeecap=1 ETH, pricebump=10%, lifetime≈3h. (geth.ethereum.org)
- Identify private orderflow constraints:
- For Flashbots Protect, confirm TTL (~25 blocks) and whether useMempool=true fallback is set; cancellations become public immediately if mempool fallback is enabled. (docs.flashbots.net)
- Fee strategy that actually lands
- Compute tip and headroom from current baseFee using eth_feeHistory and a conservative percentile; then add future-proofing for N blocks of baseFee growth (worst-case 1.125^N). (alchemy.com)
- For replacements, bump both maxPriorityFeePerGas and maxFeePerGas by ≥ pricebump (10% typical) and ensure maxFee ≥ projected baseFee over your target inclusion window. (geth.ethereum.org)
Practical snippet (ethers v6, EIP‑1559 Type 2):
import { ethers } from "ethers"; const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); const wallet = new ethers.Wallet(process.env.PRIVKEY!, provider); async function computeFees(targetBlocks = 3) { const hist = await provider.send("eth_feeHistory", [20, "pending", [10, 50, 95]]); const base = BigInt((await provider.getBlock("pending"))!.baseFeePerGas!); const p95 = BigInt(hist.reward.map((r: string[]) => BigInt(r[2])).reduce((a, v) => a + v, 0n) / BigInt(hist.reward.length || 1)); // worst-case baseFee growth for N blocks (12.5% per block) const growth = (bf: bigint, n: number) => { let x = bf; for (let i = 0; i < n; i++) x = (x * 1125n) / 1000n; // ~+12.5% return x; }; const tip = p95 < 1n ? 1n : p95; // avoid 0 tip on some providers const maxFee = growth(base, targetBlocks) + tip; return { maxFeePerGas: maxFee, maxPriorityFeePerGas: tip, base }; } async function replaceTx(originalNonce: number, to: string, data = "0x") { const { maxFeePerGas, maxPriorityFeePerGas, base } = await computeFees(3); const bump = (x: bigint) => (x * 110n) / 100n; // ≥10% bump const tx = await wallet.sendTransaction({ to, data, nonce: originalNonce, // SAME NONCE maxPriorityFeePerGas: bump(maxPriorityFeePerGas), maxFeePerGas: bump(maxFeePerGas), gasLimit: 200000, // or an estimate type: 2, }); console.log(`Sent replacement -> ${tx.hash}, base=${base.toString()}`); }
- Notes:
- If your initial TX omitted maxPriorityFeePerGas, explicitly set it on replacement; node defaults can make bumps “look” unchanged, triggering “replacement transaction underpriced.” (alchemy.com)
- If you use private routing, also send a public-cancel after TTL if not landed (details in step 4). (docs.flashbots.net)
- Nonce hygiene and cancellation discipline
- Confirm the blocking nonce:
- Compare getTransactionCount("pending") vs "latest". If pending > latest, you have queued TXs in the mempool. Replace or cancel the lowest pending nonce first. (docs.chainstack.com)
- Cancel pattern (EOA):
- Send a 0-value transfer to self with the same nonce and a bumped fee (as above). Remember: replacement requires ≥10% bump and both maxPriority/maxFee increases on many clients. (geth.ethereum.org)
- Beware caps:
- If your cancel TX triggers “tx fee exceeds the configured cap (1.00 ether),” you must switch to a node with higher RPCTxFeeCap or self-host and raise/disable it. (newreleases.io)
- Provider routing that balances privacy and inclusion
- Private-first, public-fallback:
- Use Flashbots Protect with useMempool=true to fall back after 25 blocks or when a proposer lacks MEV‑Boost; cancellations forward to public mempool immediately to clear nonces. (docs.flashbots.net)
- Expectation-setting:
- Flashbots inclusion speeds are strong (>97% within 3 blocks in some public benchmarks), but still configure fallbacks to avoid tail-latency outliers. (marketplace.quicknode.com)
- L2-aware runbook (Arbitrum/OP/Base)
- Inclusion != finality: post‑Dencun, L2 fees are cheaper thanks to blobs (separate fee market), but sequencers apply their own timeouts and per‑tx caps; e.g., Base enforces a per‑transaction gas max and rejects higher limits before inclusion. (coinmarketcap.com)
- Explicit timeouts:
- Arbitrum express lane applies a 5‑block timeout for buffered submissions; unsequenced TXs drop with no explicit “timeout error”—always check receipts. (docs.arbitrum.io)
- Force-inclusion pathway:
- If you suspect censorship/outage, you can submit via the L1 Delayed Inbox and “force include” after the window; build this into incident runbooks. (docs.arbitrum.io)
- Smart accounts (ERC‑4337) specifics
- Different mempool, different rules:
- Bundlers accept at most one UserOperation per sender+nonce unless replacing with higher maxPriorityFeePerGas and proportionally higher maxFeePerGas; sanity checks include minimums relative to the next block’s basefee. (eips-wg.github.io)
- Optimizing verification costs:
- High verification gas or paymaster issues will stall UserOperations pre-bundle—simulate handleOps locally before broadcast. (eips.ethereum.org)
- Node/operator controls (if you self-host for observability/SOC 2)
- Tune txpool and RPC limits to your profile:
- txpool.pricebump=10 (or policy-aligned), txpool.globalslots/queue sized for your flow, txpool.lifetime≈3h for non-executable TXs, RPCTxFeeCap increased or disabled for admin speed-ups. (etclabscore.github.io)
- Expose txpool APIs to internal tools only; many hosted nodes don’t expose them at all. (geth.ethereum.org)
- Document changes and approvals to your fee policy under SOC 2 change management; log all replacements/cancellations with before/after fee params and block inclusion outcomes.
Actionable mini-runbooks (copy/paste)
A) Quick “What’s blocking me?” probe
# 1) Compare nonces curl -s $RPC -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionCount","params":["0xYourAddr","latest"]}' curl -s $RPC -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":2,"method":"eth_getTransactionCount","params":["0xYourAddr","pending"]}' # 2) Fetch pending baseFee curl -s $RPC -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":3,"method":"eth_getBlockByNumber","params":["pending",false]}' # If self-hosted Geth: curl -s $RPC -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":4,"method":"txpool_status","params":[]}'
Use the lower pending nonce as the first candidate for replacement/cancel; ensure your replacement bumps both maxPriority and maxFee by ≥10%. (docs.chainstack.com)
B) Safe cancel pattern (EOA)
const cancel = await wallet.sendTransaction({ to: await wallet.getAddress(), value: 0, nonce: BLOCKING_NONCE, // same nonce maxPriorityFeePerGas: bump(tip), // ≥10% maxFeePerGas: bump(headroom), // ≥10% and >= baseFee projection gasLimit: 21000, type: 2 });
If you see txfeecap errors, switch to a node with a higher RPCTxFeeCap or self-host and raise it. (newreleases.io)
C) Private-first with public fallback (Flashbots Protect)
- Default retries ~25 blocks; add useMempool=true to forward stalled private TXs to public mempool after TTL. Cancellations are forwarded immediately when mempool fallback is on. (docs.flashbots.net)
D) L2 Arbitrum nuance checklist
- If express-lane buffered >5 blocks without sequencing, expect silent dropping; re-submit with proper sequenceNumber or switch to normal path. For critical operations during sequencer issues, submit via L1 delayed inbox and force inclusion after the window. (docs.arbitrum.io)
Emerging best practices (2025–2026)
- BaseFee projection is not optional: plan for at least 2–3 blocks of worst-case +12.5% baseFee growth when setting maxFee, to reduce retries and cost volatility. (eips.ethereum.org)
- Build fee estimators on eth_feeHistory percentiles, not eth_gasPrice; expose slow/avg/fast tiers and a “land in ≤3 blocks” tier backed by private routing. (alchemy.com)
- Post‑Dencun L2 ops: treat blob gas as a separate market; don’t conflate cheap L2 execution with guaranteed inclusion under sequencer policies. Monitor blob fee markets and sequencer health in the same dashboard that tracks your inclusion SLOs. (coinmarketcap.com)
- Account Abstraction drift: consolidate your EOA and 4337 fee/nonce policies—engineers often fix EOAs and forget bundler mempool rules, leading to phantom stalls in AA paths. (eips-wg.github.io)
Proof — GTM metrics we align to (and how we measure)
- Inclusion SLOs:
- Private routing baseline can achieve >97% inclusion within 3 blocks; we set internal SLOs to “≥95% in 3 blocks, ≥99% in 6” with public fallback and replacement logic. We verify via per‑address mempool telemetry and block receipts, exported to your BI. (marketplace.quicknode.com)
- Fewer stuck tickets:
- By enforcing nonce hygiene and automatic cancel/replace after M blocks, teams typically see a sharp drop in “my transaction is stuck” tickets. We quantify as “tickets per 1,000 TXs” pre/post rollout; this rolls into procurement’s ROI model via reduced support handle time.
- Spend predictability:
- Fee estimation on feeHistory percentiles + baseFee projection reduces overbidding dispersion and failed-replace churn. We track “effectiveGasPrice variance” and “retry rate,” then translate to hard-dollar savings and forecast accuracy. (alchemy.com)
- Compliance evidence (SOC 2):
- We deliver runbooks, change logs, and parameter diffs (e.g., txpool.pricebump, RPCTxFeeCap) plus approvals, tying replacements/cancels to tickets and providing audit-grade artifacts.
Where 7Block fits in your roadmap
- Architecture and implementation:
- We integrate this playbook into your stack via our smart, wallet, and node workstreams. See our smart contract and protocol specialists: smart contract development and custom blockchain development services.
- Platform integration:
- Private routing with public fallback, multi-RPC orchestration, and observability wiring (txpool dashboards, fee SLOs) through our blockchain integration.
- Risk and hardening:
- Preflight checks and continuous linting for fee/nonce policies as part of our security audit services.
- DeFi-facing stacks:
- For teams running swaps/bridges in production, we apply L2‑aware inclusion policies and gas optimization as part of our DeFi development services and cross‑chain solutions.
Appendix — quick references for your engineers
- EIP‑1559 (type 0x02), baseFee elasticity and spec. (eips.ethereum.org)
- gas estimation via eth_feeHistory and baseFee-aware fee tiers. (alchemy.com)
- Geth txpool defaults (pricebump=10%, lifetime≈3h, slots/queues). (etclabscore.github.io)
- RPC fee cap (RPCTxFeeCap) behavior and default 1 ETH. (newreleases.io)
- Flashbots Protect config, TTL, mempool fallback. (docs.flashbots.net)
- ERC‑4337 bundler mempool replacement rules. (eips-wg.github.io)
- Dencun / EIP‑4844 blob fee market and L2 fee impact. (coinmarketcap.com)
- Base and Arbitrum L2 transaction policy nuances. (docs.base.org)
Business outcome you can take to procurement
- Reduced support load: fewer stuck-TX tickets; traceable drop in handle time.
- Predictable spend: lower fee variance and fewer failed replacements.
- Faster time-to-finality: measurable inclusion SLOs that map to user-facing KPIs.
- Audit-ready ops: SOC 2–friendly change management and telemetry for fee/nonce policy.
If you want this automated and observable instead of tribal knowledge, we’ll wire it into your stack with CI checks, dashboards, and on-call runbooks—backed by SLOs, not vibes.
Bold but simple next step
- Book a 90-Day Pilot Strategy Call
Internal links for deeper work:
- Web3 engineering and protocol builds: web3 development services
- End-to-end dApps: dApp development
- Asset operations and tokenization: asset tokenization, asset management platform development
Final reminder
- Don’t fight the mempool—instrument it. Replace with policy, not guesswork. Pay for inclusion, not for retries. And always assume baseFee can rise 12.5% per block while your ops team sleeps. (eips.ethereum.org)
Book a 90-Day Pilot Strategy Call
Like what you're reading? Let's build together.
Get a free 30‑minute consultation with our engineering team.

