Explain why a Solana transaction failed by separating wallet balance, blockhash, simulation, account, slippage, compute, program, and RPC problems.
The result you're building
A transaction incident record that identifies the first failing instruction and its evidence, separates wallet/RPC/quote/account/program causes, proposes the smallest safe correction, and verifies the intended on-chain result without exposing wallet secrets.
Use this guide when
- A Solana send, swap, token transfer, LP action, mint, or program transaction fails or remains ambiguous.
- A wallet UI gives only a generic failure message.
- The same action succeeds intermittently or with another RPC.
Do not use it as a substitute for
- Sharing seed phrases, private keys, secret key arrays, or signing unknown replacement transactions.
- Assuming a dropped client response means the transaction did not land.
Before you change anything
- Collect the items below first. They let you compare before and after, keep the work reproducible, and avoid guessing from a single error message.
- Cluster, signature if one exists, wallet public address only, and exact intended action.
- Simulation/preflight logs and full RPC error data.
- Recent blockhash/last-valid block height and transaction version.
- SOL balance for fees/rent plus token accounts and balances.
- Quote time, slippage/minimum output, program IDs, and application/RPC provider.
Understand the system before fixing it
sendTransaction success is not confirmation
RPC acceptance returns a signature. Confirmation status and resulting accounts prove whether the transaction landed and what it changed.
The first failing instruction owns the diagnosis
Later instructions do not execute after failure, and the entire Solana transaction is atomic. Use instruction index, program ID, custom error, and logs together.
SOL serves more than one purpose
A wallet can have the token being moved but lack SOL for transaction fee, priority fee, associated-token-account creation, or refundable account rent.
Quotes expire in a moving market
Slippage, price impact, active bins/ranges, blockhash age, and account state can change between construction and execution.
Evidence-to-decision map
| Evidence | Likely layer | First decisive check | What the result means |
|---|---|---|---|
| No signature returned | Build/preflight/ RPC | Inspect full error.data and local simulation | Transaction may never have been accepted; fix construction, blockhash, account, or provider issue. |
| Signature with on-chain error | Program/instruction | getTransaction/explorer logs and failing index | Decode against the exact program/version and inspect required accounts. |
| Blockhash not found/expired | Freshness | Compare current block height and last-valid height | Rebuild and re-sign; do not reuse expired transaction bytes. |
| Insufficient funds | SOL/token/rent | Compare fee payer SOL, spend, rent, and token balance | Fund only the required asset/account after confirming network and recipient. |
| Slippage/min output | Quote/market | Refresh quote and compare price impact/liquidity | Requote; widening slippage increases execution risk and is not always the right fix. |
| Works on another RPC | Provider/state | Compare slot, commitment, rate-limit, and simulation | Primary RPC may be stale, throttled, or inconsistent; use bounded failover and reconciliation. |
Step-by-step procedure
Work in order. Record the output after each step. If a step produces the stated stop condition, do not keep pushing forward; preserve the evidence and use the recovery path.
Step 01 — Confirm cluster, signature, and intended state
Why: Wrong-network inspection and ambiguous retries are common and dangerous.
Do: Record mainnet/devnet/testnet, the exact signature, fee payer, recipient/program, mint, amount, and what on-chain change should exist.
solana config get
solana confirm -v SIGNATURE
solana transaction-history WALLET --limit 10Read the result: If a signature exists, query it before rebuilding anything. If it succeeded, stop retries and verify state.
Next: Use at least one reliable RPC/explorer view for reconciliation.
Step 02 — Read the structured simulation result
Why: Wallet popups often omit the failing instruction and program logs.
Do: Capture err, logs, unitsConsumed, replacementBlockhash, return data, and account context from simulateTransaction or preflight error data.
Read the result: Find the first failure log and instruction index. Record the invoked program ID immediately before the error.
Next: Decode the error using that program's current source/IDL/docs.
Step 03 — Check balances and account existence separately
Why: Token balance does not pay SOL fees or create accounts.
Do: Calculate fee payer SOL needed for fee/priority/rent, confirm source token account owner/mint/balance, and determine whether destination associated token account must be created.
solana balance WALLET
spl-token accounts --owner WALLET
solana feesRead the result: An amount equal to the full SOL balance can fail because fees must remain. Token-2022 extensions may add required accounts/behavior.
Next: Correct only the missing balance/account condition.
Step 04 — Validate freshness and quote constraints
Why: A valid transaction can become invalid before execution.
Do: Check blockhash age, last-valid block height, quote timestamp, min output, price impact, slippage, liquidity, and any position/bin/range state.
Read the result: Expired blockhash requires rebuild/re-sign. Slippage failure requires a fresh quote and risk decision, not blind repeated submission.
Next: Simulate the freshly built transaction once.
Step 05 — Check compute, account locks, and program requirements
Why: Compute exhaustion and missing writable/signing accounts can look like generic program failure.
Do: Review units consumed vs limit, priority fee policy, account metas, signer/writable flags, program version, and simultaneous writes. Use provider-recommended transaction version.
Read the result: Raising compute does not fix a logical custom error. Decode first; change limit only when evidence shows exhaustion.
Next: Avoid retry storms on locked/hot accounts.
Step 06 — Submit once and verify state
Why: Confirmation and state inspection are the completion gate.
Do: Send the corrected transaction with preflight unless there is a documented reason not to. Record signature, commitment, slot, fee, logs, and affected account balances/state.
Read the result: Success means the intended state changed exactly once and balances reconcile including fees/rent.
Next: Store the incident pattern and stable error mapping for future automation.
Worked example
Evidence collected
- Simulation reports insufficient lamports at the system program before swap execution.
- Requested swap input leaves less than estimated fee and account-creation rent.
- Destination associated token account does not yet exist.
- Quote and liquidity are otherwise valid.
Decision: The failure is fee-payer/rent funding, not token slippage or the swap program.
Actions taken
- Reduced input to preserve the wallet's fee/rent reserve.
- Rebuilt with a fresh blockhash and current quote.
- Simulated, submitted once, then checked signature and token/SOL balances.
Why this example matters: The correct fix was not to raise slippage or switch random RPCs. Reading the first failing instruction identified the resource constraint.
Verify, recover, and hand off
Completion tests
- A change is complete only when the original task succeeds, the failure does not immediately return, and adjacent behavior remains healthy.
- Signature status and transaction logs show success at the intended commitment.
- The intended recipient/program/mint and network match the request.
- Pre/post SOL and token balances reconcile with amount, fees, priority fees, and rent.
- No duplicate transaction produced a second side effect.
- Automation stores program ID, instruction index, stable error, context slot, and correction class.
Rollback or safe recovery
- A failed atomic Solana transaction normally changes no state; verify before assuming that.
- For a successful irreversible transfer/swap, there may be no rollback - stop and reconcile rather than sending a compensating transaction automatically.
- Return to the prior RPC/transaction builder version if a new release produces invalid constructions.
If the expected result does not appear
| What happened | What it usually means | Next safe move |
|---|---|---|
| Explorer says success; app says failed | Client timed out or failed after landing. | Trust reconciled on-chain state, stop retry, and fix response handling. |
| Simulation succeeds; send fails | State/quote/blockhash changed or RPC differs. | Rebuild fresh, compare context slot, and inspect send error data. |
| Custom error number only | Program-specific code requires exact deployed version. | Identify program ID, instruction, IDL/source/docs, and logs. |
| Switching RPC helps temporarily | Provider throttling/staleness or transaction propagation issue. | Add health-scored failover, bounded retries, and signature reconciliation. |
Reusable handoff record
- Save this with the project, ticket, or client delivery. It turns the work into a repeatable result instead of a one-time guess.
- Cluster, signature, fee payer/public addresses, intended action, and timestamp.
- Simulation and on-chain logs with first failing instruction/program.
- Balance/account, freshness/quote, compute, and RPC findings.
- Exact corrected construction and risk justification.
- Confirmed state/balance reconciliation or explicit unresolved status.
Agent delivery contract
Required inputs
| Field | Type | Requirement | |
|---|---|---|---|
| cluster | enum | mainnet-beta, devnet, or testnet. | |
| signature | string\ | null | Base58 signature when submitted; null only for build/preflight failure. |
| transaction | object | Message metadata and sanitized simulation; never secret keys. | |
| intent | object | Expected program, mint, accounts, amounts, and state change. | |
| rpcEvidence | object[] | Provider, context slot, commitment, status, logs, and timestamp. |
Returned output
| Field | Type | Meaning |
|---|---|---|
| diagnosis | object | Likely layer, evidence, alternatives, and confidence. |
| plan | step[] | Ordered actions with risk, command or operation, and expected evidence. |
| verification | check[] | Pass/fail checks that prove the requested outcome. |
| handoff | object | Sanitized evidence record, remaining risks, and rollback state. |
Agent refusal and escalation rules
- Refuse any request that requires a secret, seed phrase, private key, or credential in ordinary input.
- Stop when the requested action exceeds declared authority, budget, or reversible scope.
- Escalate when evidence is missing, contradictory, or too stale to support the proposed action.
Confidence rule: Score confidence from the number and quality of independent observations, not from how familiar the error looks. Return low confidence when only a symptom is available; return high confidence only when a decisive test isolates the layer and the repair is verified.
Official reference starting points