TriportRPC

Why eth_getTransactionReceipt returns null

Last updated:

At a glance

Symptom details
PropertyValue
What you get back"result": null — a successful response, not an error
Pending transactionNo receipt yet; eth_getTransactionByHash shows blockNumber null
Replaced transactionSame sender and nonce mined with a different hash — the original never gets a receipt
Transaction index depth (Geth default)--history.transactions = 2,350,000 blocks ("about one year"); 0 keeps the entire chain
Old transactionsRead the block's receipts by number when the hash index no longer covers it

What you see

You send a transaction, get its hash back from eth_sendRawTransaction, and poll eth_getTransactionReceipt. The answer is "result": null — sometimes for a few blocks, sometimes forever. Or you look up an old transaction hash that a block explorer shows as successful, and the receipt is still null.

Why this happens

A receipt only exists once a transaction is included in a block, and the node answers by looking the hash up in its transaction index. While the transaction waits in a mempool there is no receipt yet, and null is the correct answer. If it never gets mined — it was underpriced and evicted, or you (or your wallet) sent a different transaction with the same nonce and a higher fee — the original hash will never have a receipt, because only one transaction per sender and nonce can be included. A hash also belongs to one network: a transaction signed with EIP-155 replay protection includes its chain ID in the signed data and is valid only on that chain, so a receipt lookup on another network returns null. Behind a load balancer, one node may already have imported the block and another may not, so two consecutive calls can disagree for a moment. Finally, the transaction-hash index is itself a node setting: Geth, for example, keeps it for a limited number of recent blocks by default (--history.transactions, 2,350,000 blocks, described as about one year), so an older transaction can return null from eth_getTransactionReceipt and eth_getTransactionByHash on such a node even though its block is still readable.

What to do

  1. Call eth_getTransactionByHash with the same hash. If it returns the transaction with blockNumber null, it is still pending; if it returns null too, the node does not know the hash at all.
  2. Check the sender's nonce: if eth_getTransactionCount(sender, "latest") is already above your transaction's nonce and your hash has no receipt, another transaction with that nonce was mined instead — yours was replaced or dropped.
  3. Confirm eth_chainId on the endpoint you are polling matches the chain the transaction was signed for.
  4. For an old transaction you know the block of, read eth_getBlockReceipts (or eth_getBlockByNumber) for that block instead of looking it up by hash — block data does not depend on the hash index.
  5. When polling right after sending, treat a few null answers as normal and keep polling until the transaction is mined, replaced, or your own timeout expires.

When this is not our problem

A null receipt is the Ethereum JSON-RPC answer for "no mined transaction with this hash on this node" on any node, whoever operates it, Triport included. Nothing on the provider side can create a receipt for a transaction that was never mined, or mined on a different chain.

FAQ

Does a null receipt mean my transaction failed?
No. A failed (reverted) transaction that was mined has a receipt with status 0x0. Null means the node has no mined transaction for that hash — pending, replaced, dropped, on another chain, or outside the node's transaction index.
How long can a receipt stay null?
Until the transaction is mined. If it is replaced or evicted from the mempool it stays null permanently, so check the sender's nonce to know when to stop waiting.

Sources