Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A failed Solana transaction and an expired Solana transaction are different things. When an instruction fails during execution, Solana rolls back that transaction’s instruction-level state changes but still charges the transaction fee. The recent blockhash can remain usable until the transaction reaches its validity limit. If an application treats an error, a missing status, or a slow confirmation as permission to immediately build and sign a replacement, the original transaction may still land—or the user may be asked to authorize the same intent twice.

The safe rule is to retain the original signature, message, blockhash, and lastValidBlockHeight. Query the original signature, and use block height to determine expiry. Only after the original outcome is settled or its blockhash has expired should you build a replacement. A replacement has a different signed message, so every required signer must sign again.

What “failed” means on Solana

A Solana transaction passes through several stages that are easy to conflate:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Message construction: the application chooses the fee payer, recent blockhash or durable nonce, instructions, account list, and instruction data.
  2. Signing: each required signer authorizes the exact message bytes.
  3. Submission and validation: the cluster checks signatures, account requirements, blockhash or nonce validity, and other transaction rules.
  4. Execution: the runtime runs the instructions and reports success or an error.
  5. Confirmation: an RPC node reports how far the transaction has progressed according to a selected commitment.

An execution error means the transaction reached the runtime and an instruction failed. State changes made by the transaction’s instructions are reverted, but the fee is still charged. The signature identifies that particular attempt; it does not become a reusable authorization for a different attempt.

#1 Best Overall
Ledger Nano X - Classic Crypto Wallet with Bluetooth | Compact, go anywhere, 1.1" display. Desktop & iOS/Android compatible
  • Effortlessly build your crypto portfolio via the all in one Ledger Wallet app: buy, sell, send, receive, swap, stake and more across popular blockchains. 15,000+ coins & tokens in a single dashboard. Keep a close eye on the market. Compare service providers. Track performance. Get timely alerts. Build your portfolio with confidence.
  • Enjoy Bluetooth connectivity, iOS access, and hours of battery use with this mobile-first, secure backup signer. Freedom you can depend on.
  • Genuine Check: confirm your signer is authentic during setup with the Ledger Wallet app.
  • Protect your signer: keep it in mint condition at all times with a bespoke Pod or Case to avoid scratches and everyday wear and tear.

Failure therefore does not automatically mean expiry. A transaction can have an execution error while the recent blockhash that was included in its message is still inside the cluster’s processing-age window. Conversely, a transaction can disappear without an execution error because its blockhash expired before the cluster processed it.

Why a failed transaction can still be valid

Execution result and lifetime are separate

Solana records the result of executing a transaction separately from the time during which the transaction is eligible for processing. The runtime can reject an instruction, roll back its instruction state changes, and charge the fee while the message’s recent blockhash remains recent enough to be accepted by the transaction pipeline.

This distinction matters to retry code. “The instruction failed” answers what happened when the transaction executed. “Is this signed message still eligible to be processed?” answers a different question. A retry decision must account for both.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The recent-blockhash window is measured in slots

Solana’s transaction reference documents a recent-blockhash processing-age limit of 150 slots. A slot is not a fixed number of seconds, so 150 slots must not be converted into a hard-coded wall-clock timeout. Congestion, skipped slots, and cluster conditions can change the elapsed time.

When an application obtains a recent blockhash, the RPC response also provides lastValidBlockHeight. Save that value with the transaction. It is the transaction-specific expiry boundary and is more reliable than “wait 30 seconds” or another guessed timer.

A missing status is not proof of expiry

Applications commonly submit a transaction and then call getSignatureStatuses. A status can be temporarily absent because the RPC node has not observed the transaction, the transaction is outside that node’s short status cache, forwarding was delayed, or the node is answering at a different commitment. A null status does not prove that the signed message can no longer land.

Likewise, “not confirmed” and “expired” are not synonyms. Confirmation is a report about observed commitment. Expiry is determined from the transaction’s blockhash lifetime. Treating an uncertain status as an automatic retry signal is how duplicate signing and duplicate transfers begin.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recent-blockhash transactions: the safe retry procedure

The following sequence applies to an ordinary transaction that uses a recent blockhash. It separates submission, observation, expiry, and rebuilding so that a user is not asked to sign the same intent twice while the first message may still be processed.

Rank #2
Sale
TANGEM Crypto Wallet Pack of 3 – Trusted Cold Storage Hardware Wallet | 100% offline; Bitcoin, Ethereum, NFTs & altcoins; No seed phrase; NFC; Pack of 3, Self custody wallet
  • Proven security at scale: Over 9 years and millions of cards issued with no known remote hacks, while military‑grade EAL6+ security keeps your private keys locked inside the chip. Your cryptocurrencies stay strongly protected from online attackers.
  • Tap once to manage your entire crypto wallet across 90 blockchains - no USB cables or Bluetooth, no batteries, no setup. Access 14,100+ coins & tokens, DeFi, NFTs, and staking instantly from your phone
  • Smart backup: Use your second Tangem Wallet as your Backup keys with end‑to‑end encryption; no more papers, pictures. If one card is lost, the remaining can still restore full access, with an optional seed phrase available for advanced users.
  • Engineered to last up to 25 years: Waterproof (IP69K), shockproof and tested for extreme temperatures from −25°C to 50°C. A durable cold wallet with long‑term protection and independently audited security.
  • Trusted by 6 million users worldwide (4.9 App Store, 4.8 Google Play) - buy, sell, swap, stake, and spend cryptocurrency directly. The secure offline storage wallet designed for how people actually use crypto wallets

1. Save the complete attempt before asking for a signature

When calling getLatestBlockhash, retain both returned values:

const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash(commitment);

Associate those values with the exact message being presented to the wallet or signing service. Also retain an application-level operation ID, the fee payer, the account set, the instruction parameters, and the eventual signature. This record lets the backend distinguish a retry of one user action from a new action.

2. Sign one message and submit it once

Compile the message with the saved blockhash, collect all required signatures, serialize the signed transaction, and submit it. Store the returned signature immediately. Do not discard it just because the submission call times out or an RPC node returns an uncertain response.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If a wallet signs locally, the application should persist the operation state before moving the user to a “try again” screen. The screen can say that the result is pending; it should not launch a second signing request merely because the first submission did not produce an immediate confirmation.

3. Query the same signature

Use getSignatureStatuses for the original signature, not for a newly generated transaction. Select a commitment—such as confirmed or finalized—that matches the application’s settlement policy and use it consistently for status and block-height checks.

const result = await connection.getSignatureStatuses([signature]);
const status = result.value[0];
// status.err: execution or transaction error, if the node reports one
// status.confirmationStatus: processed, confirmed, finalized, or null

If the status reports an execution error, show the user that this attempt failed and that its fee was charged. Do not silently submit a second transaction under the assumption that the first signature is irrelevant. Keep the original attempt associated with the operation until your retry policy has settled it.

4. Check expiry by block height

For an unconfirmed or otherwise uncertain attempt, poll getBlockHeight at the same chosen commitment:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const currentHeight = await connection.getBlockHeight(commitment);
const expired = currentHeight > lastValidBlockHeight;

Continue tracking the original signature while the current block height is at or below the saved lastValidBlockHeight. Once the current height exceeds that value, the recent-blockhash transaction has expired and can no longer be processed with that blockhash. An official Solana cookbook expiry check uses this block-height comparison.

Rank #3
TANGEM Crypto Wallet Pack of 2 – Trusted Cold Storage Hardware Wallet | 100% offline; Bitcoin, Ethereum, NFTs & altcoins; No seed phrase; NFC, Self custody wallet
  • Seedless by design, nothing to steal: Your private key is generated inside the EAL6+ chip and never leaves it. No seed phrase is shown or typed at setup, so a tampered device, keylogger, or phishing site has nothing to capture. 9+ years, millions of card.
  • Tap once to manage your entire crypto wallet across 90 blockchains - no USB cables or Bluetooth, no batteries, no setup. Access 16,100+ coins & tokens, DeFi, NFTs, and staking instantly from your phone
  • Backup without a seed phrase: Your wallet is copied to 2 backup cards with end-to-end encryption, so there are no words on paper to lose or leak. Keep them in separate places; if one card is lost, the others restore full access. Optional seed phrase for advanced users.
  • Engineered to last up to 25 years: Waterproof (IP69K), shockproof and tested for extreme temperatures from −25°C to 50°C. A durable cold wallet with long‑term protection and independently audited security.
  • Trusted by 6 million users worldwide - buy, sell, swap, stake, and spend cryptocurrency directly. The secure offline storage wallet designed for how people actually use crypto wallets

5. Rebuild only after the outcome is settled or the blockhash has expired

When the original transaction is confirmed at the commitment your application requires, stop. If it reports an execution error, record the failed attempt and decide whether the business operation is safe to retry. If it remains uncertain, wait until the block-height test proves expiry before creating a new recent-blockhash transaction.

After expiry, fetch a fresh blockhash and construct a new message. The new blockhash changes the message bytes, so collect every required signature again. A previous signature does not authorize the rebuilt message.

6. Make the retry visible and idempotent

Give the replacement a new attempt record while keeping it linked to the same user operation. Before submitting, check whether the original signature has already reached the required commitment. If it has, do not send the replacement. This check belongs on the backend as well as in the user interface; a browser tab can close, refresh, or issue two requests concurrently.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why changing a transaction requires new signatures

Signatures cover the serialized message, not an abstract description such as “send these tokens.” Changing any signed field produces different message bytes. Solana’s partial-signing documentation specifically identifies the fee payer, blockhash, instruction order, account list, and instruction data as changes that invalidate signatures already collected.

That has several practical consequences:

  • Replacing an expired blockhash requires all required signers to sign the new message.
  • Changing the fee payer requires new signatures, even if every instruction is otherwise identical.
  • Adding, removing, or reordering an account or instruction requires new signatures.
  • Changing an amount, destination, memo, or other instruction data requires new signatures.
  • A signature from the first attempt must never be copied onto a message whose bytes have changed.

“Avoid signing twice” therefore has two meanings. First, do not prompt a person to authorize a second transaction while the first may still succeed. Second, do not assume that a signature can be carried onto a rebuilt transaction. If rebuilding is justified, it is a genuinely new signing event and must be presented as such.

Recent blockhash versus durable nonce

Durable nonce transactions use a nonce account instead of relying on the ordinary recent-blockhash window. They are designed for delayed or offline signing, but their retry behavior is different and must not be mixed with recent-blockhash logic.

Concern Recent-blockhash transaction Durable-nonce transaction
Lifetime Limited by the recent-blockhash processing-age window; save and check that attempt’s lastValidBlockHeight. The stored nonce removes the ordinary recent-blockhash expiry window, enabling delayed or offline signing. Solana documentation currently warns that durable nonces may be deprecated in a future release, so verify their status before designing new systems around them.
Execution failure Instruction state changes revert, while the transaction fee remains charged. The nonce advancement and fee remain committed even when a later instruction fails.
Safe next attempt Wait for the original result or prove expiry, then fetch a fresh blockhash, rebuild, and collect signatures again. Refetch the nonce after processing, build a fresh message, and run a new signing flow. Do not reuse the old signed transaction.
Main danger A late or missing status is mistaken for expiry, causing an unnecessary replacement. A consumed nonce is treated as reusable, or nonce validation failures are confused with post-validation instruction failures.

How nonce consumption changes the retry rule

A durable-nonce transaction advances the nonce before its other instructions execute. If a later instruction fails, the nonce advancement is still committed and the fee is still charged. The old signed transaction therefore cannot be submitted as a fresh attempt: its nonce has already been consumed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

After any processed durable-nonce attempt, read the nonce account again. Build the next transaction with the updated nonce and obtain all required signatures for that new message. A nonce transaction that fails validation before execution is a separate case: an already-used nonce, an invalid or missing nonce account, or a missing authority signature can cause the transaction to be dropped without fees or state changes. Do not apply that no-fee validation rule to a transaction that passed validation and then failed an instruction.

Rank #4
DCENT Hardware Wallet | Biometric Cold Storage, Bluetooth, Multi-Crypto
  • EAL5+ CERTIFIED SECURE ELEMENT + FINGERPRINT PROTECTION — Your private keys stay encrypted offline on a certified EAL5+ chip, the same security tier used in EMV bank cards. Built by DCENT, securing crypto since 2018. Fingerprint authentication adds a second layer no PIN-only wallet can match.
  • 10,000+ ASSETS NATIVE ON 100+ BLOCKCHAINS — Hold Bitcoin, Ethereum, XRP, Solana, Cardano, popular stablecoins (USDT, USDC), and NFTs in one wallet. No third-party apps, no fragmented setup — every supported asset works straight out of the box.
  • TAP-TO-SIGN MOBILE EXPERIENCE — Pair your wallet with the DCENT mobile app over Bluetooth. Manage tokens, review transactions, and access in-app swap features directly from your phone — no cables, no desktop required.
  • WEB3 & dAPP ACCESS VIA METAMASK — Connect to MetaMask and other browser extension wallets to manage NFTs, claim airdrops, and access dApps. A large screen and intuitive 4-button interface keep every transaction clearly visible before you sign.
  • SEAMLESS FIRMWARE UPDATES & 30-DAY MONEY-BACK GUARANTEE — Apply security updates without resetting your wallet or migrating funds. Backed by Amazon's 30-day money-back guarantee — your purchase is risk-free.

Common errors and what they do—and do not—tell you

Instruction execution error

The transaction reached execution and an instruction returned an error. Its instruction-level state changes are reverted and the fee is charged. The error explains why that attempt did not complete; it does not by itself tell your application that a recent-blockhash message has expired.

AlreadyProcessed

The transaction pipeline can reject a message that is already present in its status cache, keyed to the message hash. This protects against processing the same message twice, but it is not a substitute for application-level retry control. A separate rebuilt message can still represent the same business operation, so your application must keep an operation ID and check the original signature before creating a replacement.

BlockhashNotFound

This indicates that the blockhash is no longer in the recent queue for an ordinary transaction. It is a blockhash-validity failure, not evidence that an instruction executed and failed. A transaction using a durable nonce follows different validation rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Nonce validation failure

An already-used nonce, missing or invalid nonce account, or missing nonce-authority signature can cause rejection before execution. In that documented validation-failure path, there are no transaction fees or instruction state changes. Confirm whether the transaction failed during validation or after nonce advancement and instruction execution before explaining the fee outcome to a user.

Implementation pattern for a backend

A robust sender stores an attempt record rather than treating an RPC call as the whole transaction lifecycle. At minimum, store:

  • an application operation ID;
  • the serialized message or a hash of the exact message bytes;
  • the signature, when available;
  • the recent blockhash and lastValidBlockHeight, or the durable nonce value;
  • the required commitment and current state, such as created, submitted, confirmed, failed, or expired;
  • the business effect being attempted, such as a withdrawal identifier or order identifier.

The state machine should make submission idempotent. A second request for the same operation first loads the existing attempt. If the signature is confirmed, it returns that result. If the attempt is still within its blockhash lifetime, it returns a pending state and continues polling rather than asking for another signature. If the attempt has expired, it creates a new attempt linked to the original and starts a new signing flow.

if (attempt.signature) {
  const status = await getSignatureStatus(attempt.signature);
  if (status?.confirmationStatus === requiredCommitment) return "settled";
  if (status?.err) return "failed-at-execution";
}

if (attempt.lastValidBlockHeight !== undefined) {
  const height = await getBlockHeight(commitment);
  if (height <= attempt.lastValidBlockHeight) return "still-live";
  return "expired—rebuild and sign a new message";
}

// Durable nonce path: refetch the nonce account before rebuilding.
return "inspect nonce and create a fresh signing flow";

This pattern does not guarantee that an RPC provider will forward every submission or expose identical timing. It does ensure that uncertain transport behavior does not automatically become a second wallet prompt or a duplicate business operation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

User-interface safeguards

Show one operation, not one prompt per network attempt

Display a stable operation identifier and the original signature when one exists. A “pending” state should explain that the network has not reached the selected commitment and that the application is checking the original transaction. Avoid a button labeled “retry” that immediately opens the wallet; first check the stored attempt and its expiry.

Best Value
Trezor Safe 7 Crypto Hardware Wallet with Bluetooth for Android/iOS/Desktop | Charcoal Black, Aluminum Unibody, 2,5" TouchScreen, Wireless Charging, Quantum-Ready, IP54, Long-Lasting LiFePO? Battery
  • Dual-chip architecture for maximum protection: The next-gen, fully auditable TROPIC01 chip works alongside a certified EAL6+ Secure Element—completely NDA-free—to deliver radically transparent, industry-leading defense against physical attacks.
  • Quantum-ready security: Get protection against future threats with the first-ever hardware wallet designed with quantum-ready architecture.
  • See every detail with confidence: Our largest high-resolution color touchscreen makes it easy to navigate your assets, review transactions and manage your coins with clarity.
  • Wireless freedom with encrypted Bluetooth control: Manage, buy, swap and stake securely using Trezor Suite on desktop or mobile. Qi2-compatible wireless charging keeps your Trezor powered up. No cables required—security meets convenience.
  • Works seamlessly with Android, iOS and desktop: Connect wirelessly or via USB-C to your phone or computer. Manage your crypto anywhere with our companion Trezor Suite app.

Explain fees accurately

For an execution failure, tell the user that instruction state changes were rolled back but the transaction fee was charged. Solana’s transaction reference lists a base fee of 5,000 lamports per signature, but fee schedules can change; present any numeric fee only when it has been read from the current network or current documentation. A validation failure before execution, particularly in the documented durable-nonce cases, has different fee behavior.

Require confirmation before a business retry

Even after a transaction expires, determine whether retrying is safe for the underlying operation. For a transfer, check the application’s own ledger or withdrawal record so that a late observation of the original cannot create a second payout. Protocol-level expiry handling and business-level idempotency solve different problems.

Troubleshooting decision tree

The wallet says the transaction failed and the fee changed

Look up the original signature and inspect its error. If it is an execution error, the attempt reached the runtime; instruction state changes were reverted and the fee was charged. Fix the instruction or its inputs before retrying. Do not interpret the fee as proof that a replacement is safe to sign immediately.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The submission timed out and no signature is visible

First determine whether the client actually received a signature locally. If it did, retain and query that signature. If it did not, inspect the sender’s durable operation record and any RPC response before asking the user to sign. Check the saved blockhash lifetime; a timeout is a transport symptom, not an expiry result.

getSignatureStatuses returns null

Continue checking the original signature and compare the current block height with the saved lastValidBlockHeight. Do not submit a replacement while the transaction remains within its validity window. Once the height exceeds the boundary, mark the attempt expired and rebuild with a fresh blockhash.

The replacement was rejected as already processed

Check whether the replacement reused exactly the same message or whether the original message was already processed. An identical message can be recognized by the transaction pipeline, while a changed message needs new signatures and may still duplicate the same business action. Resolve the operation through the original signature and application record rather than repeatedly submitting variants.

A durable-nonce retry fails unexpectedly

Read the nonce account and determine whether the nonce advanced. If it advanced, the previous nonce transaction has been consumed—even if a later instruction failed—and cannot be reused. Build with the current nonce and collect signatures again. If the nonce did not validate, inspect the nonce account, authority signature, and account configuration; that pre-execution path has different fee consequences.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Checklist for avoiding accidental double signing

  • Save blockhash and lastValidBlockHeight from the same getLatestBlockhash response.
  • Persist the operation ID before requesting a wallet signature.
  • Store the exact signed message and returned signature.
  • Submit a given signed transaction once and query that same signature.
  • Use one declared commitment for status and block-height decisions.
  • Treat a missing status or timeout as uncertainty, not expiry.
  • Use getBlockHeight and the saved boundary rather than a fixed seconds-based timer.
  • Wait for confirmation, a reported execution result, or proven blockhash expiry before creating a replacement.
  • After expiry, fetch a fresh blockhash and collect every required signature again.
  • For durable nonces, refetch the nonce after processing and never reuse a consumed nonce transaction.
  • Keep protocol attempts linked to a business-level idempotency record.

The practical rule

A Solana error describes an execution or validation result; it does not automatically describe the lifetime of the signed message. Recent-blockhash transactions remain eligible until their blockhash expires, while durable-nonce transactions consume the nonce as part of processing. Track the original signature and lifetime, decide expiry with block height, and rebuild only when the original attempt is settled or genuinely expired. When you rebuild, treat it as a new message and obtain new signatures from every required signer.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.