name debugging-moonbeam description Debugs issues in the Moonbeam parachain including runtime panics, EVM execution failures, XCM message delivery problems, and client-side errors. Use when encountering transaction failures, unexpected behavior, state inconsistencies, block production issues, or RPC errors. license MIT OR Apache-2.0
Debugging Moonbeam
Contents
Lazy Loading (Fork Mode)
Lazy loading allows running a local Moonbeam node that fetches state on-demand from a live RPC endpoint. This is the most powerful tool for debugging production issues as it lets you replay transactions against real chain state.
Building with Lazy Loading
cargo build --release --features lazy-loading
Basic Usage
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbeam.network \
--sealing 6000
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbeam.network \
--lazy-loading-block 0x1234...abcd \
--sealing 6000
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonriver.moonbeam.network \
--sealing 6000
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbase.moonbeam.network \
--sealing 6000
Advanced Options
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbeam.network \
--lazy-loading-runtime-override ./target/release/wbuild/moonbeam-runtime/moonbeam_runtime.wasm \
--sealing 6000
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbeam.network \
--lazy-loading-state-overrides ./state-overrides.json \
--sealing 6000
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbeam.network \
--lazy-loading-delay-between-requests 100 \
--lazy-loading-max-retries-per-request 5 \
--sealing 6000
State Overrides File Format
{
"0x1234..." : {
"balance" : "0x1000000000000000000" ,
"nonce" : "0x0" ,
"code" : "0x..." ,
"storage" : {
"0x0" : "0x1234"
}
}
}
Debugging Workflow with Lazy Loading
Reproduce a production issue :
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbeam.network \
--lazy-loading-block 0xBLOCK_BEFORE_ISSUE \
--ethapi=debug,trace \
--sealing manual
Replay the failing transaction :
const tx = await prodProvider.getTransaction (txHash);
const trace = await localProvider.send ('debug_traceCall' , [{
from : tx.from ,
to : tx.to ,
data : tx.data ,
value : tx.value ,
gas : tx.gas
}, 'latest' , { tracer : 'callTracer' }]);
Test runtime fixes :
cargo build --release -p moonbeam-runtime
./target/release/moonbeam \
--lazy-loading-remote-rpc https://rpc.api.moonbeam.network \
--lazy-loading-runtime-override ./target/release/wbuild/moonbeam-runtime/moonbeam_runtime.wasm \
--sealing 6000
Performance Considerations
Initial requests may be slow (state is fetched on-demand)
Use a reliable, non-rate-limited RPC endpoint
Consider running your own archive node for heavy debugging
Expect ~20x slower execution compared to local state
Common Use Cases
Use Case Configuration Debug failed tx Fork at block before tx, replay with tracing Test migration Use --lazy-loading-runtime-override with new runtime Simulate whale actions Use --lazy-loading-state-overrides to modify balances Test governance Override voting power via state overrides Debug precompile Fork + trace precompile calls
Debugging Workflows
Runtime Debugging
Identify the failing component :
Check logs for WARN or ERROR messages
Look for panic messages with stack traces
Identify which pallet or module is involved
Reproduce locally :
RUST_LOG=debug ./target/release/moonbeam --dev --alice --sealing 6000 --rpc-port 9944
RUST_LOG=pallet_parachain_staking=trace ./target/release/moonbeam --dev
Add debug logging in the pallet:
use frame_support::log;
log::debug!(target: "pallet-name" , "Debug info: {:?}" , value);
Check storage state :
Use Polkadot.js Apps to inspect storage
Query via RPC: state_getStorage
EVM Debugging
Enable EVM tracing :
./target/release/moonbeam --dev --ethapi=debug,trace
Use debug_traceTransaction :
const trace = await provider.send ('debug_traceTransaction' , [txHash, {}]);
Check precompile calls :
Precompile addresses are deterministic (0x0000...0800+)
Look for revert reasons in trace output
Verify input encoding matches expected ABI
Common EVM issues :
Gas estimation failures: Check precompile gas costs
Revert without reason: Look at precompile error handling
State differences: Compare with expected EVM state
XCM Debugging
Enable XCM logging :
RUST_LOG=xcm=trace ./target/release/moonbeam --dev
Check XCM message structure :
Verify multilocation encoding
Check weight limits
Verify asset representation (local vs foreign)
Common XCM issues :
TooExpensive: Insufficient weight/fee
UntrustedReserveLocation: Asset origin mismatch
AssetNotFound: Asset not registered
Test XCM locally :
zombienet spawn zombienet/moonbeam.toml
Client/RPC Debugging
Check RPC method availability :
curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method":"rpc_methods"}' http://localhost:9944
Verify client version compatibility :
Ensure client matches runtime version
Check spec_version in runtime
Debug connection issues :
wscat -c ws://localhost:9944
Block Production Debugging
Check collator status :
Verify author mapping: AuthorMapping.MappingWithDeposit
Check nimbus keys are registered
Monitor block production :
RUST_LOG=cumulus=debug ./target/release/moonbeam
Common block issues :
Missed slots: Check collator selection
Invalid blocks: Check weight limits
Orphaned blocks: Check finality
Key Log Targets
Target Component pallet_evmEVM execution pallet_ethereumEthereum transaction processing xcmXCM message handling cumulusParachain consensus moonbeam_rpcCustom RPC methods frontierEthereum compatibility layer
Useful RPC Methods for Debugging
eth_getTransactionReceipt (txHash)
debug_traceTransaction (txHash, {tracer : 'callTracer' })
eth_getStorageAt (address, slot, blockNumber)
txpool_content ()
eth_getBlockByNumber (blockNumber, true )
Test-Driven Debugging
Write a failing test :
describeSuite ({
id : "Dxxxxxx" ,
title : "Bug reproduction for issue #xxxx" ,
foundationMethods : "dev" ,
testCases : ({ context, it } ) => {
it ({ id : "T01" , title : "Reproduces the bug" , test : async () => {
}});
}
});
Run the test :
cd test && pnpm moonwall test dev_moonbase Dxxxxxx
Files to Check
Runtime logs: Check frame_support::log outputs
Precompile errors: /precompiles/*/src/lib.rs - look for Err() returns
XCM barriers: /runtime/*/xcm_config.rs - check barrier implementations
Weight limits: /runtime/*/weights/ - verify weight calculations
Common Error Patterns
Dispatch Errors
Error Likely Cause Investigation BadOriginWrong caller type Check origin requirements InsufficientBalanceNot enough funds Check free vs reserved balance StorageOverflowArithmetic overflow Check bounded types TooManyDelegationsHit delegation limit Check MaxDelegationsPerDelegator
EVM Errors
Error Cause Debug Steps OutOfGasGas limit too low Increase gas, check precompile costs RevertContract/precompile failure Check revert reason, trace tx InvalidNonceNonce mismatch Check pending txs, use eth_getTransactionCount IntrinsicGasBase gas cost not met Ensure gas >= 21000 + calldata
Precompile Errors
revert ("Invalid input" )
revert ("Not enough balance" )
revert ("Permission denied" )
Err (PrecompileFailure::Error { exit_status: ... })
Investigation Tools
Polkadot.js Apps
Developer → Chain State → Select pallet → Query storage
Developer → Extrinsics → Submit test calls
Developer → RPC Calls → Raw RPC queries
Substrate Debug Tools
subkey inspect --public "0x1234..."
subxt explore --url ws://localhost:9944
frame-omni-bencher v1 metadata --runtime path/to/runtime.wasm
Reproducing Issues
From Transaction Hash
const tx = await api.rpc .eth .getTransactionByHash (txHash);
const receipt = await api.rpc .eth .getTransactionReceipt (txHash);
const rawTx = await context.createTxn !({
to : tx.to ,
data : tx.input ,
value : tx.value ,
gas : tx.gas ,
});
await context.createBlock (rawTx);
From Block State
npx @acala-network/chopsticks@latest \
--config chopsticks/moonbeam.yml \
--block 5000000
Performance Debugging
Identify Slow Extrinsics
RUST_LOG=runtime::executive=trace ./target/release/moonbeam --dev
Profile Weights
log::info!(
target: "benchmark" ,
"Extrinsic weight: reads={}, writes={}, compute={}" ,
weight.proof_size (),
weight.ref_time ()
);
Memory Debugging
RUST_BACKTRACE=1 cargo test --release -- --nocapture
heaptrack ./target/release/moonbeam --dev
Network Debugging
Sync Issues
curl -H "Content-Type: application/json" \
-d '{"id":1,"jsonrpc":"2.0","method":"system_peers"}' \
http://localhost:9944
curl -H "Content-Type: application/json" \
-d '{"id":1,"jsonrpc":"2.0","method":"system_syncState"}' \
http://localhost:9944
Finality Issues
RUST_LOG=grandpa=debug ./target/release/moonbeam
curl -H "Content-Type: application/json" \
-d '{"id":1,"jsonrpc":"2.0","method":"chain_getFinalizedHead"}' \
http://localhost:9944
Debugging Checklist
Identify the failing operation (extrinsic, RPC, block)
Check logs for error messages
Reproduce on local dev node
Enable relevant debug logging
Trace execution path
Identify root cause
Write failing test
Implement fix
Verify fix passes test
Check for regressions