Debug Solana Transaction Simulation

Use simulateTransaction and preflight logs to debug failed Solana transactions before changing routes, signers, or RPC providers.

Debug Solana Transaction Simulation

Simulation is the cheapest place to learn why a Solana transaction will fail.

Use this page when a transaction fails before confirmation, preflight returns logs, or a swap/backend flow is stuck on a vague "simulation failed" message. The goal is not to explain every Solana program error. The goal is to preserve the right evidence, classify the failure, and decide whether to rebuild, retry, or escalate.

For broad submit/confirm flow, use Transaction Lifecycle. For HTTP and JSON-RPC status triage, use RPC Errors Reference.

Part of the Carbium Solana infrastructure stack.


What Simulation Answers

simulateTransaction asks an RPC node to evaluate a signed transaction without submitting it to the cluster. Solana also uses simulation during sendTransaction preflight unless your client disables preflight.

Read simulation as a diagnostic checkpoint:

SignalWhat it tells you
errThe transaction would fail if submitted in the simulated state
logsProgram logs and instruction-level clues
unitsConsumedCompute used during simulation, when available
accountsOptional returned account data if requested
replacementBlockhashA newer blockhash suggestion when replacement is requested

The official Solana RPC docs define these fields for simulateTransaction. The sendTransaction docs also state that preflight verifies signatures and simulates the transaction before submission unless preflight is disabled.


Start With The Failure Boundary

Before changing code, identify where the failure happened.

Failure boundaryWhat to inspect firstUsual next page
Quote request failedHTTP status, auth header, route responseSwap API Errors Reference
txn was missinguser_account, request family, route availabilityQ1
Simulation failederr, logs, instruction index, compute hintsThis page
Blockhash expiredquote age, wallet approval delay, resend policyBlockhash Expiry Recovery Playbook
Signature was submitted but unclearsignature status, duplicate-send policySending Transactions through Carbium RPC

This distinction prevents a common bad loop: switching RPC providers when the transaction itself is malformed, stale, underfunded, or built for a different account state.


Minimal Simulation Call

Most applications use a Solana client library, but the underlying JSON-RPC call looks like this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "simulateTransaction",
  "params": [
    "BASE64_SIGNED_TRANSACTION",
    {
      "encoding": "base64",
      "sigVerify": true,
      "replaceRecentBlockhash": false,
      "commitment": "processed"
    }
  ]
}

Use a signed transaction for the most realistic result. If your simulation disables signature verification, do not treat it as proof that the real signed send path is healthy.

When you are relaying through Carbium RPC, point your Solana client at your backend-held RPC endpoint:

https://rpc.carbium.io/?apiKey=YOUR_RPC_KEY

Keep the RPC key server-side. Simulation is a debugging tool, not a reason to expose authenticated infrastructure URLs in frontend code.


Read The Error Like A Debugger

When simulation fails, preserve the full response before rebuilding the transaction.

{
  "value": {
    "err": {
      "InstructionError": [2, { "Custom": 6001 }]
    },
    "logs": [
      "Program ... invoke [1]",
      "Program log: Slippage tolerance exceeded",
      "Program ... failed: custom program error: 0x1771"
    ],
    "unitsConsumed": 94123
  }
}

The important parts are:

  • instruction index: which instruction failed
  • program logs: the closest human-readable explanation
  • custom error: a program-specific code, not a universal Solana error
  • compute usage: whether compute budget may be part of the problem

Do not reduce this to "RPC failed." The RPC node is reporting what the runtime observed during simulation.


Common Patterns And Next Checks

Simulation patternLikely causeNext check
InstructionError with custom program codeProgram-specific rule failedRead program logs, route metadata, and app assumptions
Logs mention slippage or output thresholdQuote is stale or price movedRequote and compare destAmountOutMin
Logs mention missing account or owner mismatchWrong token account, ATA, signer, or mintVerify wallet, token mint, and account derivation
Compute budget exceededTransaction needs different compute policyReview compute instructions before send
Blockhash not found or too oldTransaction aged out before sendUse the blockhash recovery page
Signature verification failurePayload was not signed as expectedCheck signer boundary and serialized transaction handling

For Carbium Swap API flows, keep quote-stage and send-stage logs separate. A good support record should show the quote parameters, returned route metadata, transaction handoff, simulation response, submitted signature if any, and final confirmation status.


Preflight: Default On, Skip Only Deliberately

sendTransaction can run preflight simulation before submitting the transaction. Leaving preflight on is the safer default for wallets, dashboards, onboarding flows, and support-heavy apps because it catches obvious failures before users or systems wait for confirmation.

Skipping preflight can be reasonable for latency-sensitive backends that already validated the transaction path and accept the tradeoff. Make that a product decision, not a copy-pasted default.

Use casePreflight default
Wallet or consumer appKeep preflight on
New integrationKeep preflight on until logs are boring
Backend executor with strong quote validationConsider skipping only after measurement
Debugging a failureRun simulation or enable preflight

If you skip preflight and the send path fails later, you still need equivalent logs somewhere else. Speed without observability usually makes incidents slower, not faster.


Production Logging Checklist

Before a Solana transaction flow goes live, make sure your logs can answer:

  • which user or app request created the transaction
  • which quote or route response produced the payload
  • which wallet or signer signed it
  • whether simulation/preflight ran
  • what err, logs, and unitsConsumed said
  • whether a signature was submitted
  • what final signature status returned

Redact API keys, authenticated RPC URLs, private keys, and user-sensitive data before sharing logs in support channels.

📘

If simulation says the transaction would fail, rebuild from the cause. If submission already returned a signature, check signature status before creating a new transaction.

🔶

Building transaction-heavy Solana flows with Carbium? Keep simulation evidence, quote logs, and signature status together so failures can be fixed instead of guessed.