Transaction simulation failed
Error·3 min read
Your wallet rejected the transaction before it reached the chain, which is good news: nothing was spent. The useful part is the code hiding behind the message.
Before a wallet sends anything, it asks an RPC node to run the transaction against the current state of the chain. If that dry run fails, the wallet stops and shows you this. No transaction was submitted, no fee was paid, and nothing in your wallet changed.
Why is this message so unhelpful?
Because it is a wrapper, not a cause. The actual reason is a program error code returned by whichever on-chain program rejected the instruction, and most wallets bury it. You will see variations like:
Transaction simulation failed: Error processing Instruction 0insufficient funds. simulation failed. err 1Simulation failed. custom program error: 0x1
That trailing number is the part that matters. err 1 and custom program error: 0x1 are the same thing written two ways, one in decimal and one in hex.
How do I find the real error?
Three places, in order of how quickly they give you an answer.
The wallet itself. Phantom and Solflare both put the full message behind a details or expand control on the rejection dialog. It is usually one click away and people rarely look.
The browser console. Open developer tools before you retry. A simulation failure logs the program logs, which name the instruction and the error. This is the most reliable route in a browser.
The app you are using. A well-built app catches the simulation result and translates it. If the interface only repeats “simulation failed” and offers you nothing else, that is a quality signal about the app, not about your wallet.
What do the common codes mean?
Codes in the 0x range come from the token program when the failing instruction is a token one. The three you are most likely to hit around token accounts:
0x1is InsufficientFunds, and it refers to the token, not your SOL. What to do about 0x1.0xbis NonNativeHasBalance: you are closing an account that still holds something. What to do about 0xb.0x23is AccountHasWithheldTransferFees, a Token-2022 account with fees parked inside it. What to do about 0x23.
A different family of failure shows up as Transaction results in an account with insufficient funds for rent. That one is not a program error at all but the runtime refusing to leave an account below its rent minimum, and it has its own explanation.
Is a failed simulation dangerous?
No, and it is worth understanding why. Simulation runs against a recent snapshot of state without signing or submitting anything. A rejection means the network never saw the transaction. You have lost nothing except the attempt.
The one thing worth checking is whether you were about to sign something you did not intend. A simulation failure is a good moment to read the instruction list rather than clicking retry. How to read a Solana transaction covers what to look for.
It fails, then works on retry. Why?
Simulation uses a recent blockhash and a recent view of state. If an account changed between the moment the app built the transaction and the moment the node simulated it, the dry run fails on state that is already stale. Rebuilding the transaction fixes it, which is what a retry does.
This is common when you are closing many accounts at once and something in the batch moved in the meantime. If a retry keeps failing on the same code, it is not a timing problem and the code is telling you something real.