TRON transaction pending, expired or not found: what each means for a USDT transfer
TRON makes a block every three seconds, so five minutes on the chain is a hundred blocks. A USDT transfer still shown as pending after that is in one of four places: signed but never broadcast, accepted by a node but not yet in a block, in a block that is not yet irreversible, or final on chain and waiting for the receiving platform to credit it. Two other words tend to turn up along the way: an explorer that cannot find the hash, and a node that calls the transaction expired. Each has its own fix, and one of the fixes, applied too early, pays for the same transfer twice.
Every transaction carries its own deadline
The block interval is a constant of the protocol, 3,000 milliseconds. The other number is inside the transaction. When a wallet builds a transfer it writes an expiration time into raw_data, the part that gets signed, and every node checks it. A transaction whose expiration has passed is refused, and so is one whose expiration lies more than a day past the node's head block. The node's word for both is TRANSACTION_EXPIRATION_ERROR.
A second pair of fields ties the transaction to a recent block. ref_block_bytes and ref_block_hash name a block the network still holds, and a node remembers the last 65,536 blocks, about 54 hours of chain. A reference older than that, or one taken from a test network, earns TAPOS_ERROR instead. The clock on both starts when the transaction is built.
Four things "pending" can mean
Signed, never broadcast
A wallet or a payout script can sign a transfer and then never hand it to a node, after a timeout or a crash between signing and sending. The transfer has a hash all the same, because the hash is computed from the transaction's own bytes. It is the SHA-256 of raw_data, and it exists before any node has seen anything. A hash in your logs proves that the transfer was built. An explorer that answers "not found" for it is right: no node it reads from holds those bytes.
Accepted by a node, not yet in a block
A node that takes a transaction answers at once and holds it in its pool of pending transactions until a block carries it. Acceptance and inclusion are separate events, and our own order statuses keep them apart: in mode B, where we broadcast a transfer the client signed, broadcasted means a node accepted the transaction and says nothing yet about a block. On a three-second chain this state is short. A node can also accept a transaction that no block ever carries, usually because it was dropped from that pool. Such a transfer is gone for good when its expiration passes.
In a block, not yet irreversible
The newest blocks at the head of the chain can still be replaced. TRON keeps a second pointer behind the head, the latest solidified block, which is the newest one the network treats as irreversible, and a node serves both. The distance between them is how long a transfer sits in a block without being final. We read both pointers once from a public full node, with two calls made at the same moment.
| Read on 27 October 2026, 21:27 UTC | Block number | Block time, UTC |
|---|---|---|
| Latest block | 87,487,718 | 21:27:06 |
| Latest solidified block | 87,487,699 | 21:26:09 |
| Gap | 19 blocks | 57 seconds |
The gap in block numbers and the gap in timestamps agree at three seconds a block. Our mode B items reach confirmed only after solidification, which our API reference puts at about a minute, and the read is in line with it. That gives the usual answer to how long a USDT transfer takes on TRON: a block every three seconds, and finality about a minute later. It is a single read from one node. We have not measured how the gap moves over a day, or our own orders' times from delivery to broadcast to block.
Final on chain, not yet credited
An exchange or a payment processor credits a deposit after a count of blocks that it sets for itself. We do not know any platform's count and do not quote one. Before asking the platform, read the result written beside the transfer. A transfer can be in a block and still have failed, with the fee spent and no tokens moved, and anything other than SUCCESS in that place is a failure (what OUT_OF_ENERGY means, and the other ways a USDT transfer fails). A successful transfer in a solidified block has reached the recipient's address. What remains is the platform's bookkeeping, and its support can trace that from the hash.
What expired means, and how to send again
Past its expiration a transaction cannot enter any block. Every node refuses it, so broadcasting the same signed bytes again only collects another refusal. The recovery is a new transaction: build the transfer again, with a fresh expiration and a reference to a recent block, and sign it.
The rebuild does not pay twice. A transaction that no block carried was never executed: it moved no tokens and burned nothing, because a transfer spends its energy and its TRX while it runs in a block. Once a transaction is in a block, no node will run it a second time. The one way to send the money twice is to sign a replacement while the original can still land. A node judges the expiration against the time of its head block, which can trail your clock, so a block made in the last seconds before the deadline can still carry the original, and a lagging node or explorer may not show it yet. The software that built the original holds it and can read raw_data.expiration, in milliseconds since the epoch. Wait until the latest solidified block is past that moment, which in our read takes about a minute longer, and then ask a node by hash. If the node still does not know the transaction, the original can no longer land, and the new transfer is the only one.
Pending and expired on an energy order
Rented energy adds a second clock. When the energy for an order is delivered, the order carries send_before, the lease less three seconds: 297 seconds on the five-minute lease and 3,597 on the hour. The window is counted from the delegation we saw confirmed, and the lease on the chain started a block and a polling cycle before that, so treat the last seconds of the window as already gone (how long rented energy lasts). A transfer that reaches a block after the energy has left the wallet burns the sender's TRX at the protocol rate of 100 sun a unit, about 6.5 TRX for a transfer to an address that holds USDT.
What happens when the window closes depends on who sends. In mode A you broadcast the transfer yourself. We watch the network, mark the item sent when your transfer appears, and send the order.item.sent webhook with its hash in data.txid. If no transfer has appeared by send_before, the item becomes expired and is charged, because the energy was delivered.
In mode B you hand us a signed transaction and we broadcast it as soon as the energy lands (how mode B works). The item moves through broadcasting and broadcasted to confirmed, the last only after solidification. We never broadcast after send_before: an item we did not send in time closes as failed with error: broadcast_window_missed, and the hold comes back in full. The window there is also capped by the transaction's own expiration, less a margin for the broadcast, so a transaction that reaches us with little life left gets a short window.
Mode B checks the expiration on the way in as well. When we receive the transaction it needs at least 180 seconds of life left and no more than 23 hours 59 minutes. A deadline too far ahead comes back as 400 invalid_request with details.reason set to expiration_too_far, and too little life as the same 400 with details.index alone. Both answers come before any energy is bought.
What to check, in order
- Whether a node ever accepted the transaction. The software that sent it holds the node's answer, or it holds nothing because the broadcast never happened. A hash settles nothing on its own, since it exists before any broadcast.
- Whether the hash is found, on an explorer or from a node asked by hash. If it is not found and the expiration is still ahead, broadcast the same signed bytes again. If the latest solidified block is past the expiration and the hash is still not found, build a new transaction and sign it.
- The result beside a hash that is found.
SUCCESSmeans the transfer went through. Anything else means it ran and failed, and the fee is already spent. - Whether its block is solidified. In our read the newest irreversible block trailed the head by about a minute, so a successful transfer younger than that is still settling.
- The receiving platform's own count of blocks, and after that its support, with the hash.
- On an order of ours, the item:
sentwith itstxidin mode A,confirmedin mode B. When the window closed first, mode A showsexpiredand mode B showsfailedwitherror: broadcast_window_missed. A mode Bexpiredmeans a node refused the transaction for what it is, or the transaction reverted in a block, and it is charged.
Watch an item sit at ready and then turn expired with nothing real at stake: the sandbox has a recipient whose transfer never comes →