{"id":269,"date":"2026-08-23T12:02:00","date_gmt":"2026-08-23T16:02:00","guid":{"rendered":"https:\/\/dolanduck.io\/blog\/?p=269"},"modified":"2026-08-23T12:02:00","modified_gmt":"2026-08-23T16:02:00","slug":"solana-blockhash-transaction-expired","status":"publish","type":"post","link":"https:\/\/dolanduck.io\/blog\/solana-blockhash-transaction-expired\/","title":{"rendered":"Why Solana Transactions Expire: Blockhashes Explained 2026"},"content":{"rendered":"\n<p>A Solana transaction expires because every transaction carries a recent blockhash that stays valid for only 150 blocks \u2014 roughly a minute of real time. Once the network moves past that window the transaction becomes permanently invalid and cannot be processed, no matter how well-formed it is. This is deliberate: Solana has no mempool holding pending transactions indefinitely, so the blockhash acts as both a timestamp and a deduplication key. &#8220;Transaction expired&#8221; and &#8220;blockhash not found&#8221; are the same event described from different angles, and they are the single most common reason a memecoin buy silently does nothing.<\/p>\n\n\n<!--more-->\n\n\n<h2 class=\"wp-block-heading\">Key Facts<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>A blockhash is valid for 150 blocks, which at normal block times works out to roughly 60-90 seconds.<\/li><li>Expired transactions cost nothing. No fee is charged because they were never included in a block.<\/li><li>The blockhash doubles as replay protection \u2014 the same signed transaction cannot be submitted twice.<\/li><li>Solana has no persistent mempool. A transaction that is not included quickly is simply dropped.<\/li><li>Durable nonce accounts replace the recent blockhash with a stored nonce, removing the time limit entirely.<\/li><li>The clock starts when the blockhash is fetched, not when you click confirm \u2014 a slow signing step eats the window.<\/li><li>Expired is not the same as failed: a failed transaction is on-chain with an error, an expired one leaves no trace.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What a Blockhash Is Doing in Your Transaction<\/h2>\n\n\n\n<p>Before your wallet can build a transaction it asks an RPC node for a recent blockhash \u2014 the hash of a block produced moments ago. That value goes into the transaction and gets covered by your signature. When a validator receives it, it checks whether the blockhash appears in its list of the last 150 blocks. Present means fresh, process it. Absent means either too old or fabricated, reject it.<\/p>\n\n\n\n<p>The mechanism does two jobs at once. It bounds how long a signed transaction stays dangerous, so a transaction you signed and abandoned last week cannot suddenly execute. And it makes each transaction unique without needing an incrementing account nonce like Ethereum&#8217;s, because the same instruction signed against two different blockhashes produces two different signatures. Since <a href=\"\/blog\/proof-of-history-solana\/\">block ordering is fixed before consensus runs<\/a>, &#8220;150 blocks ago&#8221; is unambiguous to every node without any of them comparing clocks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Expired, Failed, Dropped: Three Different Outcomes<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><\/th><th>Expired<\/th><th>Failed<\/th><th>Dropped<\/th><\/tr><\/thead><tbody><tr><td>Reached a leader<\/td><td>Possibly, too late<\/td><td>Yes<\/td><td>No<\/td><\/tr><tr><td>On-chain record<\/td><td>None<\/td><td>Yes, with error code<\/td><td>None<\/td><\/tr><tr><td>Fee charged<\/td><td>No<\/td><td>Yes<\/td><td>No<\/td><\/tr><tr><td>Typical cause<\/td><td>Blockhash aged past 150 blocks<\/td><td>Slippage, insufficient funds, program error<\/td><td>Priority fee too low, RPC issue<\/td><\/tr><tr><td>Safe to retry<\/td><td>Yes<\/td><td>Yes, after fixing the cause<\/td><td>Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Retrying is always safe with an expired transaction, which is the reassuring part. The old signature is dead, so there is no risk of both attempts landing and double-spending. The frustrating part is that expiry gives no feedback \u2014 the wallet spins, then reports nothing happened, with no error to read on an explorer because the transaction never existed on-chain.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why It Happens Most When It Matters Most<\/h2>\n\n\n\n<p>Expiry rates spike during exactly the moments people care about: a token trending, a launch filling, a chart moving fast. The reason is queueing. When blocks are full, a transaction paying an uncompetitive priority fee sits behind higher bidders block after block, and 150 blocks pass in about a minute. It never gets rejected \u2014 it just ages out. This is why <a href=\"\/blog\/solana-transaction-fees-priority-fee\/\">priority fee settings<\/a> and expiry are the same problem viewed from two ends: the fee determines whether you clear the queue before the clock runs out.<\/p>\n\n\n\n<p>Human latency compounds it. The blockhash is fetched when the interface builds the transaction, not when you approve it. Sit on a confirmation dialog for forty seconds deciding whether to buy and you have spent half the window before the transaction leaves your machine. Hardware wallet confirmations, slow RPC endpoints and browser extension prompts all eat into the same budget. Routers such as <a href=\"https:\/\/jup.ag\" rel=\"nofollow\">Jupiter<\/a> refresh quotes and blockhashes periodically for this reason, and a stale quote sitting open is usually a stale blockhash too.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Durable Nonces: The Escape Hatch<\/h2>\n\n\n\n<p>For cases where a minute is not enough \u2014 multisig approvals collected over hours, offline signing, scheduled payments \u2014 Solana provides durable nonce accounts. Instead of a recent blockhash, the transaction references a nonce stored in a dedicated on-chain account, which stays valid until that nonce is advanced. This removes the time limit at the cost of maintaining an account with its own rent deposit and a strict rule that the nonce advance must be the first instruction. It is infrastructure for coordination, not something a retail trader needs, but it explains why some transactions on <a href=\"https:\/\/solscan.io\" rel=\"nofollow\">Solscan<\/a> show a nonce account among their inputs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Expiry Means for a $DOLAN Buy<\/h2>\n\n\n\n<p>DOLAN Duck ($DOLAN) launched fair, with no presale and no allocation reserved for anyone, so a fixed 98.3M supply had to distribute itself across roughly 10,700 wallets through ordinary transactions competing for ordinary block space. Every one of those buys had about a minute to land before its blockhash went stale. That is the unglamorous mechanic behind &#8220;I tried to buy and nothing happened&#8221; \u2014 not a broken token, not a blocked wallet, just a transaction that aged out in a queue. The practical response is to raise the priority fee and resubmit promptly rather than clicking repeatedly, and to keep confirmation time short when a token is moving. Traders who understand this stop blaming contracts, which is also the mindset that makes <a href=\"\/blog\/buy-solana-memecoins-no-kyc-2026\/\">self-custody buying flows<\/a> workable instead of frustrating.<\/p>\n\n\n\n<div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1754640901\"><strong class=\"schema-faq-question\">Why do Solana transactions expire?<\/strong> <p class=\"schema-faq-answer\">Every transaction carries a recent blockhash valid for only 150 blocks, roughly a minute. If it is not included in a block within that window it becomes permanently invalid, which prevents old signed transactions from executing later.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1754640902\"><strong class=\"schema-faq-question\">How long is a Solana blockhash valid?<\/strong> <p class=\"schema-faq-answer\">About 60 to 90 seconds. The limit is 150 blocks rather than a fixed time, so the real window stretches slightly when blocks are produced more slowly than the 400 ms target.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1754640903\"><strong class=\"schema-faq-question\">Do I pay a fee for an expired transaction?<\/strong> <p class=\"schema-faq-answer\">No. An expired transaction was never included in a block, so nothing was executed and no fee was charged. Only transactions that reach a block pay, including ones that fail with an error.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1754640904\"><strong class=\"schema-faq-question\">What is the difference between a failed and an expired transaction?<\/strong> <p class=\"schema-faq-answer\">A failed transaction is on-chain with an error code and cost a fee. An expired transaction never made it into a block, leaves no record on any explorer, and cost nothing.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1754640905\"><strong class=\"schema-faq-question\">Is it safe to retry an expired transaction?<\/strong> <p class=\"schema-faq-answer\">Yes, always. The expired signature is permanently invalid, so there is no risk of both attempts executing. Raise the priority fee before resubmitting if the network is busy.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1754640906\"><strong class=\"schema-faq-question\">What is a durable nonce on Solana?<\/strong> <p class=\"schema-faq-answer\">A durable nonce account stores an on-chain nonce that replaces the recent blockhash, removing the expiry window entirely. It is used for multisig approvals and offline signing where a transaction must stay valid for hours.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1754640907\"><strong class=\"schema-faq-question\">Why does waiting before confirming cause failures?<\/strong> <p class=\"schema-faq-answer\">The blockhash is fetched when the interface builds the transaction, not when you approve it. Deliberating for a minute at the confirmation screen can consume the entire validity window before the transaction is even sent.<\/p> <\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>A Solana transaction expires because every transaction carries a recent blockhash that stays valid for only 150 blocks \u2014 roughly a minute of real time&#8230;.<\/p>\n","protected":false},"author":2,"featured_media":354,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-269","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blockchain"],"_links":{"self":[{"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/posts\/269","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/comments?post=269"}],"version-history":[{"count":1,"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/posts\/269\/revisions"}],"predecessor-version":[{"id":431,"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/posts\/269\/revisions\/431"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/media\/354"}],"wp:attachment":[{"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/media?parent=269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/categories?post=269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dolanduck.io\/blog\/wp-json\/wp\/v2\/tags?post=269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}