Node operations issues
Diagnostic flows for the operational issues node operators hit most often — slow or stopped sync, faster startup, conditional shutdown at a block height, JVM and TCP-traffic tuning, the different resultCode sync error, and the --debug 80 ms bypass.
Prerequisites
This page covers operational issues you encounter when running a TRON full node — slow or stuck block sync, JVM and OS-level tuning, conditional shutdown, the sync-stopping different resultCode error, and the debug-mode bypass for the 80 ms execution time limit.
For deployment basics (hardware, JDK choice, starting and stopping a node), see Deploy a node. For database utilities (Lite Fullnode pruning, engine conversion, LevelDB startup pre-warm), see Node maintenance toolkit.
Slow or stopped block sync
A running node falls behind Mainnet or stops applying new blocks. Three things to check in order:
1. Hardware
Recommended: 16-core CPU, 32 GB RAM, 1 TB SSD. Below that, the node may stop syncing when the chain hits a complex contract call. Verify your physical core count:
$ cat /proc/cpuinfo | grep -e "cpu cores" -e "siblings" | sort | uniq
cpu cores : 8
siblings : 16Both cpu cores and siblings should be ≥ 16 on production. See Deploy a node — hardware requirements for the full table.
2. Verification time tolerance
If hardware is borderline, raise the transaction-verification time tolerance in config.conf:
vm = {
supportConstant = false
minTimeRatio = 0.0
maxTimeRatio = 20.0 # raise to 50 on very slow hardware
saveInternalTx = false
}
maxTimeRatio multiplies the 80 ms execution budget at the verification stage — a higher value lets slow nodes accept blocks containing heavy contract calls that would otherwise time out locally.
3. JVM heap and GC
Make sure GC and heap are sized correctly:
# JDK 8
java -Xmx24g -XX:+UseConcMarkSweepGC -jar FullNode.jar -c config.conf
# JDK 17+ — CMS was removed in JDK 14, use G1GC instead
java -Xmx24g -XX:+UseG1GC -jar FullNode.jar -c config.conf-Xmx≈ 70 % of physical RAM, never exceeding it. A 16 GB host uses-Xmx12g, not-Xmx24g.- GC option must come before
-jar.
See Deploy a node — JVM flags for the full set of recommended flags.
Speed up node startup
For nodes using LevelDB, the LevelDB Startup Optimization Tool (shipped with the Toolkit JAR) pre-warms the manifest file and LevelDB metadata to reduce startup time and initial memory usage.
See the Node maintenance toolkit for the full toolkit utility list, and the Toolkit User Guide — LevelDB Startup Optimization Tool for the exact CLI invocation.
This optimization is most useful when:
- You restart the node frequently (development / staging deployments)
- Startup time is dominated by LevelDB compaction or recovery passes
Stop the node at a specific block height
For data backup or query-only operations, configure automatic shutdown in config.conf:
node {
shutdown {
# Stop at a specific time (Quartz expression)
BlockTime = "54 59 08 * * ?"
# Stop at a specific block height
BlockHeight = 33350800
# Stop after syncing N blocks since startup
BlockCount = 12
}
}
Only one of the three options can be set at a time. Setting multiple causes the node to fail to start with an error.
Once the node stops, you can back up output-directory or restart the node in query-only mode.
Query-only mode after shutdown
After the conditional shutdown, restart with --p2p-disable true to serve queries without rejoining P2P:
java -jar FullNode.jar -c config.conf --p2p-disable trueIn this mode the node does not participate in peer discovery or block sync, but the HTTP and gRPC API surface continues to work — so you can query the snapshot state without it advancing. See Deploy a node — read-only query node.
Network stability and resource usage control
For nodes that face abnormal traffic or run on memory-constrained hardware, two operational levers help control resource consumption.
Cap JVM direct memory
Set the MaxDirectMemorySize JVM parameter to bound off-heap (direct) memory. A common rule of thumb: one-quarter of physical RAM.
# 16 GB host → 4 GB direct memory cap
java -XX:MaxDirectMemorySize=4g -jar FullNode.jar -c config.confWithout this cap, direct memory can grow until the OS kills the process, producing hard-to-diagnose crashes.
Throttle TCP traffic with iptables
Use the kernel hashlimit module to bound inbound and outbound TCP rates. Two example rules — adjust the numeric thresholds to your bandwidth budget:
Outbound — limit per-destination-IP rate:
iptables -A OUTPUT -p tcp -m hashlimit \
--hashlimit-name out_limit \
--hashlimit-mode dstip \
--hashlimit-above 15mb/sec \
--hashlimit-burst 30mb \
-j DROPThis caps outbound traffic to each destination IP at 15 MB/s steady-state with a 30 MB burst window.
Inbound — limit per-source-IP rate on the P2P port:
iptables -A INPUT -p tcp --dport 18888 -m hashlimit \
--hashlimit-name in_limit \
--hashlimit-mode srcip,dstport \
--hashlimit-above 300/sec \
--hashlimit-burst 600 \
-j DROPThis caps incoming TCP packets to port 18888 (default P2P listen port) from any single source IP at 300 packets/sec with a 600-packet burst window.
hashlimit parameters:
| Parameter | Meaning |
|---|---|
--hashlimit-name | Internal label so you can identify the rule |
--hashlimit-mode | Bucket dimension: srcip, dstip, or combinations like srcip,dstport |
--hashlimit-above | Steady-state rate above which packets match |
--hashlimit-burst | Burst tolerance above the steady-state rate |
-j | Action to take when matched (commonly DROP) |
different resultCode — sync stops mid-block
different resultCode — sync stops mid-blockWhen tron.log contains different resultCode, the local node executed a transaction and produced a result different from what the block records. The node refuses to accept the block, halting sync.
The message is emitted from TransactionTrace.java:345. Older java-tron versions logged it from Manager.java, so existing logs may show different file:line locations — the message format (and the diagnosis) is stable. Three common patterns:
Expected: SUCCESS; Actual: OUT_OF_TIME
SUCCESS; Actual: OUT_OF_TIMEERROR [sync-handle-block] different resultCode
txId: ae53f8a6394d7adcc2337e0e71724f520818161cbb1f6f5d556f873b08e17c99,
expect: SUCCESS, actual: OUT_OF_TIME
Cause: the local node took longer than the 80 ms budget to execute the transaction. The producing SR did not — typically because the local hardware is slower.
Fix: meet the hardware recommendation (16 cores minimum). On borderline hardware, raise the verification time tolerance:
vm.maxTimeRatio = 50
Restart the node to apply.
Expected: OUT_OF_ENERGY; Actual: SUCCESS
OUT_OF_ENERGY; Actual: SUCCESSERROR [pool-48-thread-1] different resultCode
txId: fbe7109a993b52243dc4de4087967cebc74be739d725dc27e96eb757496bd359,
expect: OUT_OF_ENERGY, actual: SUCCESS
Cause: local databases are inconsistent — transactions that should have failed are marked as successful. Typically caused by an unclean shutdown, hardware fault, or other database corruption.
Fix: download the latest database snapshot, wipe output-directory, restore from the snapshot, and restart. Doing this re-grounds every database against a known-consistent baseline.
Expected: OUT_OF_TIME; Actual: SUCCESS
OUT_OF_TIME; Actual: SUCCESSERROR [sync-handle-block] different resultCode
txId: 4ccf1feb7da348cef4190bc5d84d09d3c37160bfbdd21a0b5fd0b1d5005ead09,
expect: OUT_OF_TIME, actual: SUCCESS
Cause: the node was started with the --debug flag, which bypasses the 80 ms execution-time check. Transactions that should have timed out are instead executed successfully locally — diverging from the block record.
Fix: remove --debug from the start-up command and restart. The node will resume normal sync.
Bypass 80 ms execution time limit for testing
The 80 ms per-transaction execution budget is enforced by default (chain parameter #13, getMaxCpuTimeOfOneTx). For certain testing scenarios — heavy-computation view/pure queries, profiling experiments — you may want to bypass the check temporarily.
Start the node with the --debug flag:
java -jar FullNode.jar -c config.conf --debugThe node skips the 80 ms timeout check when processing transactions, with no execution-time restriction. You can then use /wallet/triggerconstantcontract for queries that would otherwise time out.
Do not run--debugon a Mainnet-syncing node.Any block containing a transaction whose expected result is
OUT_OF_TIMEwill execute locally with a different outcome (SUCCESS), causing adifferent resultCodeerror and stopping sync. See the previous section for the symptom.
For testing complex contracts or long-running transactions, set up a private chain instead — see TRON private chain.
Related resources
- Deploy a node — end-to-end deployment, hardware, JVM, configuration
- Node maintenance toolkit — Toolkit JAR utilities
- Database snapshots — recover from inconsistent databases
- TRON private chain — isolated environment for risk-free testing
- Smart contract errors — application-side diagnosis when the node is healthy
- Broadcast and RPC errors — broadcast-time failures
- FAQ — Q&A hub
Updated 4 days ago