Why getTransaction returns null for an old signature
Last updated:
At a glance
| Property | Value |
|---|---|
| What you get back | "result": null — a successful response, not an error |
| Error field present | No — there is no err or error object to branch on |
| Documented cause #1 | Signature has not yet reached the requested commitment level |
| Documented cause #2 | Signature unknown to the cluster — never confirmed, or confirmed long ago and since pruned |
| How to tell those apart | Compare the transaction's slot (from your own records) against the current getFirstAvailableBlock |
| Floor not to use for this | minimumLedgerSlot — it can be lower and does not guarantee a confirmed block exists at that slot |
What you see
You call getTransaction with a signature you're confident was once valid — you logged it yourself right after sendTransaction, or a teammate points at a matching entry in a block explorer — and the response comes back as "result": null. There is no err field and no JSON-RPC error object to inspect: the call succeeded, it simply found nothing to return at the requested commitment.
Why this happens
getTransaction's own reference names two causes for a null result: the signature is unknown to the cluster, or it has not yet reached the requested commitment level. The second is straightforward — a transaction submitted moments ago may not be visible yet at commitment "finalized"; requesting it at "processed" or "confirmed" instead, or waiting and retrying, resolves it. The first cause, "unknown to the cluster," is where two very different situations produce an identical response. A signature can be unknown because it was never confirmed at all — never submitted, or submitted and dropped before landing in a block. Or it can be unknown because the node you reached did confirm it, once, and has since pruned the block it lived in: a Solana RPC node's retained ledger has a moving floor. getFirstAvailableBlock documents that floor directly — "older blocks have been purged and can no longer be fetched" — and a transaction cannot be returned once the block containing it is gone, regardless of whether the transaction itself succeeded. minimumLedgerSlot reports a related but different, and usually lower, floor: the lowest slot for which the node holds any ledger data at all, confirmed or not. A slot passing that check is not a guarantee that a confirmed block — and therefore a transaction — is still retrievable there; getFirstAvailableBlock, not minimumLedgerSlot, is the boundary that answers this question.
What to do
- Rule out the wrong-cluster mistake first: confirm the endpoint you called is actually the cluster (mainnet-beta, devnet, testnet) where the transaction was submitted — the same signature has independent, and often absent, history on each one.
- If the transaction was submitted recently, rule out confirmation lag before anything else: request commitment "processed" or "confirmed" rather than "finalized", or wait and retry. A transaction that has not yet reached the requested commitment answers null too, and that has nothing to do with retention.
- If you have a slot for the signature from your own records — a submission log, a captured websocket confirmation, a block explorer — compare it against the current result of getFirstAvailableBlock. A slot below that floor means the transaction has aged out of this node's retained history; null is the expected, correct answer for something that already happened, not a sign that it failed.
- Do not use minimumLedgerSlot for that comparison. It can report a lower slot than getFirstAvailableBlock precisely because it counts unconfirmed ledger data — a slot that clears minimumLedgerSlot can still have no confirmed block behind it, so it does not tell you whether getTransaction can return anything for that slot.
- If you never captured a slot or a signature status at submission time, a live RPC node's null cannot tell you which of the two causes applies — that distinction is not recoverable by calling getTransaction again, with different parameters, or against a different node with a shorter retention window.
When this is not our problem
A null result here is not a Triport-side failure to report: it is the correct response any RPC node gives once it no longer retains the block a transaction lived in, and the same call against any Solana RPC node's live retention window behaves the same way for the same signature, on any provider — retention depth is a property of running a node, not of who operates it. If you need to find a specific old transaction whose signature you have but whose slot you did not record, and you know an address involved in it, Triport's REST wallet history endpoint reads from a dedicated archive going back roughly 3.5 years — page through that address's history and match the signature, instead of guessing from a live node's null.
FAQ
- Is a null result from getTransaction an error?
- No. The call succeeds with result: null — there is no error code or err field, because "no confirmed transaction found at this commitment" is a valid, complete answer to the query as asked.
- How do I know if my old transaction actually succeeded, if getTransaction now returns null?
- Not from this call alone. If you have the slot the transaction landed in — from your own submission log, a captured confirmation, or an explorer — compare it against the current getFirstAvailableBlock: a slot below that floor means the transaction aged out of the node's retained history, not that it failed. Without a stored slot, a live RPC node's null cannot tell the two apart.