Broadcast and RPC errors
How TRON nodes report broadcast failures and rate-limited RPC responses — the full response-code table, the SERVER_BUSY pending-pool overflow, the TronGrid 503 rate-limit response, and what to do when a successful broadcast never appears on chain.
Prerequisites
This page is the reference for errors returned by the node when you broadcast a transaction, and for rate-limited responses from hosted RPC gateways. Errors that happen after the transaction is included in a block (on-chain execution failures like REVERT / OUT_OF_ENERGY / OUT_OF_TIME) are covered in Smart contract errors; the diagnostic categories and decoded message format are in Errors and debugging.
Broadcast response codes
A wallet/broadcasttransaction call returns a top-level code field on failure. The full set of codes the node may return:
| Code | Cause | Fix |
|---|---|---|
SIGERROR | Signature verification failed | Verify the private key used to sign matches the address sending the transaction; check the key's hex format. |
BANDWITH_ERROR | Insufficient Bandwidth before broadcast, or insufficient TRX to pay for Bandwidth, new-account creation, multisig, or memo fees; this does not indicate TVM Energy exhaustion | Query /wallet/getaccountresource and /wallet/getchainparameters, identify whether the transaction creates an account or includes multiple signatures or a memo, then add Bandwidth or TRX as needed. |
DUP_TRANSACTION_ERROR | The same txID is usually already in the current node's Pending Pool or a block. If node.rpc.trxCacheEnable is enabled, only the RPC broadcast cache may have matched | Query the original transaction and receipt by txID. Regardless of the RPC cache setting, this error does not prove that the transaction is on-chain. While it remains valid, rebroadcast the same signed transaction to another reliable synchronized node. Rebuild only after it expires and is confirmed not to be on-chain, to avoid duplicate payment. |
TAPOS_ERROR | The referenced TAPOS block number and hash do not match a recent block known to the node | Rebuild using a recent block recognized by the synchronized node. The latest solidified block is usually a more conservative choice. |
TOO_BIG_TRANSACTION_ERROR | Transaction byte size exceeds the limit (typically caused by an oversized memo) | Reduce the size of the transaction. |
TRANSACTION_EXPIRATION_ERROR | The transaction expired before reaching the mempool. Default expiration is 60 seconds (TRANSACTION_DEFAULT_EXPIRATION_TIME in Constant.java) | Broadcast the transaction before expiration. For node-built transactions, increase trx.expiration.timeInMilliseconds in your local config. For public-node APIs, the 60-second window cannot be extended. For locally-constructed transactions, set a longer expiration. |
SERVER_BUSY | The whole network is busy, or this node's pending pool is overflowing | See SERVER_BUSY below. |
NOT_ENOUGH_EFFECTIVE_CONNECTION | The node has fewer effective P2P peers than minEffectiveConnection, or it could not broadcast the transaction to any peer | Check the node's P2P peer count and synchronization state. Ensure both the node and its peers have completed synchronization, then adjust minEffectiveConnection for the network or add stable peers. When using a public API, retry through another healthy endpoint. |
OTHER_ERROR | Unknown error | Inspect the node log for detail. |
NO_CONNECTION | The node has no available P2P connections | Configure a seed.node and restart the node. |
CONTRACT_EXE_ERROR | Contract execution failed during pre-execution due to a runtime or illegal-protobuf exception | Inspect the node log for detail. |
BLOCK_UNSOLIDIFIED | The node has too many unsolidified blocks (exceeds node.maxUnsolidifiedBlocks) | Wait for the node to recover. For self-hosted nodes, you can disable the check with node.unsolidifiedBlockCheck, or raise the threshold via node.maxUnsolidifiedBlocks. |
CONTRACT_VALIDATE_ERROR | Pre-execution validation failed (system-contract validation) | The actual cause is in the message field, hex-encoded. Decode with a hex-to-string tool. See CONTRACT_VALIDATE_ERROR messages below. |
CONTRACT_VALIDATE_ERROR messages
CONTRACT_VALIDATE_ERROR messagesThe error code only means "validation failed"; the real reason is in message, hex-encoded. Common decoded messages:
| Decoded message | Cause |
|---|---|
account does not exist | The signing or recipient address has never been activated on-chain. Send it a small TRX amount first. |
Validate ... error, no OwnerAccount | The owner_address in the request is malformed or unknown. |
No contract or not a valid smart contract | The contract address in the request is wrong or points to a non-contract account. |
this node does not support constant | The node's vm.supportConstant is set to false. Common on self-built nodes — see Exchange wallet integration for required VM config keys. |
For the full hex-decode procedure and the rest of the error-category taxonomy, see Errors and debugging.
SERVER_BUSY — pending-pool overflow
If the node's number of unprocessed transactions exceeds 2,000, broadcast returns SERVER_BUSY.
Fix (self-hosted nodes): raise the pending-pool size in config.conf:
node.maxTransactionPendingSize = 5000Adjust the value to your hardware capacity. Hosted services (TronGrid) tune this themselves; if you see SERVER_BUSY against TronGrid, you are hitting a global capacity event rather than a per-node setting — retry with backoff or switch endpoints.
TronGrid 503 service temporarily unavailable
TronGrid enforces per-IP rate limits across all requests. When your access frequency exceeds the limit, TronGrid returns 4xx / 5xx error codes (most commonly HTTP 503).
Fix:
-
Always send the API key in the
TRON-PRO-API-KEYheader. Requests without a key are aggressively rate-limited or rejected outright. Header format and request handling are documented in TronGrid rate limits. -
Reduce request frequency. Limit the burst at DApp start-up; do not poll TronGrid faster than the chain produces blocks — a 3-second slot makes faster-than-3-second polling pointless.
-
Respect
Retry-Afterheaders when present. See Errors and debugging — retry strategy. -
For production volume, consider a customized TronGrid tier (submit a configuration request through the TronGrid console — limits like QPS and total rate are tuned per API key) or running your own full node. See RPC and indexer providers for the comparison.
For the full rate-limit policy, see TronGrid rate limits.
Broadcast succeeded but the transaction never appears on chain
wallet/broadcasttransaction returned {"result": true}, but gettransactioninfobyid continues to return empty after several block intervals.
Cause: the node accepted the transaction into its local mempool, but the transaction never propagated to a producing SR — usually because of network instability between the broadcasting node and the SR fleet, or because the broadcasting node itself is partitioned.
Fix:
-
Wait out the expiration window. The transaction expires 60 seconds after construction (
TRANSACTION_DEFAULT_EXPIRATION_TIMEinConstant.java). After that point you can be sure it will not land. -
Rebroadcast within the window. Submit the same signed transaction to a different node — the network deduplicates by
txID, so a duplicate broadcast returns the same hash and is harmless. If a fully-synced node accepts and propagates it, you may still get inclusion. -
After expiration, rebuild and resign. Reconstruct a fresh transaction from a current TAPOS reference, sign, and broadcast. Do not reuse the old
txID— once expired, the same payload is dead.
The safety property to internalize: a successful broadcast confirms mempool acceptance, not block inclusion. Always confirm via walletsolidity/gettransactioninfobyid before treating the operation as final. See Errors and debugging — idempotency.
Related resources
- Errors and debugging — error categories, hex decode procedure, retry strategy
- API workflow — construct, sign, broadcast lifecycle
- Confirmation semantics — distinguish broadcast acceptance, receipt availability, and solidified final state
- Smart contract errors — on-chain execution failures (REVERT, OUT_OF_ENERGY, OUT_OF_TIME)
- Node operations issues — node-side sync and stability problems
- FAQ — Q&A hub
Updated 11 days ago