This page documents every TransactionErrorCode returned in SubmitTransaction errors and how to handle each one. Error codes are grouped by their retryability and whether the transaction was sent to the network.
TransactionErrorCode
The code field of a TransactionError object. Determines whether retrying the same transaction is safe, and what remediation action to take.
Error codes are grouped into three categories:
- Permanent failures — transaction was NOT sent; rebuild required before retrying
- Temporary failures — transaction was NOT sent; same transaction can be retried
- Indeterminate — unknown whether the transaction was sent; check
structured_error.certainty
Permanent Failures
The transaction was NOT sent to the network. The error condition is not recoverable with the same transaction — rebuild and re-sign before retrying.
| Error Code | Description | Retryable | Remediation |
|---|
TRANSACTION_ERROR_CODE_INVALID_TRANSACTION | Malformed transaction structure. | No | Rebuild the transaction from scratch with valid instructions. |
TRANSACTION_ERROR_CODE_INVALID_SIGNATURE | Missing or invalid signatures. | No | Verify all required signers have called SignTransaction. |
TRANSACTION_ERROR_CODE_SIGNATURE_VERIFICATION_FAILED | Cryptographic signature verification failed. | No | Re-sign the transaction with the correct private keys. |
TRANSACTION_ERROR_CODE_ACCOUNT_NOT_FOUND | A required account does not exist on-chain. | No | Verify all account addresses in the transaction’s instructions. |
TRANSACTION_ERROR_CODE_INVALID_ACCOUNT | An account exists but is in an invalid state for this operation. | No | Inspect the account’s owner, executable flag, and data for the specific program’s requirements. |
TRANSACTION_ERROR_CODE_PROGRAM_ERROR | Program execution failed. | No | Review the instruction inputs and program requirements. Check meta_error_message from GetTransaction for details. |
TRANSACTION_ERROR_CODE_INSTRUCTION_ERROR | A specific instruction failed during execution. | No | Identify the failing instruction and correct the inputs. Check simulation logs for details. |
TRANSACTION_ERROR_CODE_PRECOMPILE_VERIFICATION_FAILED | Precompile (e.g., ed25519 or secp256k1) signature verification failed. | No | Re-sign the transaction with the correct keys. |
TRANSACTION_ERROR_CODE_INVALID_BLOCKHASH_FORMAT | The transaction’s blockhash is not valid Base58. | No | Call CompileTransaction again — the service will fetch a valid blockhash automatically. |
TRANSACTION_ERROR_CODE_TRANSACTION_TOO_LARGE | Transaction exceeds Solana’s 1232-byte size limit. | No | Reduce the number of instructions or accounts per transaction. Split into multiple transactions if necessary. |
TRANSACTION_ERROR_CODE_BLOCKHASH_NOT_FOUND | The transaction’s blockhash has expired (~150 slots after compilation). | No | Call CompileTransaction to recompile with a fresh blockhash, then re-sign. |
Temporary Failures
The transaction was NOT sent to the network. The same signed transaction can be retried without rebuilding.
| Error Code | Description | Retryable | Remediation |
|---|
TRANSACTION_ERROR_CODE_INSUFFICIENT_FUNDS | The fee payer account has insufficient SOL to pay transaction fees. | Yes | Fund the fee payer account, then retry the same transaction. |
TRANSACTION_ERROR_CODE_ACCOUNT_IN_USE | An account required by the transaction is locked by another in-flight transaction. | Yes | Wait a few seconds for the conflicting transaction to process, then retry. |
TRANSACTION_ERROR_CODE_WOULD_EXCEED_BLOCK_LIMIT | The current block is at compute capacity. | Yes | Retry on the next block (~400ms). |
TRANSACTION_ERROR_CODE_TRANSIENT_SIMULATION_FAILURE | Temporary simulation error — not related to the transaction itself. | Yes | Retry immediately. |
Indeterminate
The service cannot determine with certainty whether the transaction was sent to the network. Use structured_error.certainty (a TransactionSubmissionCertainty value) to determine the recovery strategy.
TRANSACTION_ERROR_CODE_TIMEOUT is the most dangerous indeterminate error. The request timed out, but the transaction may have been broadcast before the timeout. Do not assume it was not sent. Always check certainty and wait for blockhash expiry before deciding to resubmit.
| Error Code | Description | Likely Sent? | Remediation |
|---|
TRANSACTION_ERROR_CODE_NETWORK_ERROR | Network error during submission — could have failed at any point. | Unknown | Check certainty. Wait for blockhash expiry, then query on-chain. |
TRANSACTION_ERROR_CODE_TIMEOUT | Request timed out — transaction may have been broadcast. | Possibly | Do not resubmit immediately. Check certainty and blockhash_expiry_slot. Query on-chain after expiry. |
TRANSACTION_ERROR_CODE_NODE_UNHEALTHY | The RPC node was unhealthy — may have received the transaction. | Possibly | Check certainty. Use a different RPC node and verify on-chain. |
TRANSACTION_ERROR_CODE_RATE_LIMITED | Rate limited — whether the transaction was sent depends on where limiting occurred. | Unknown | Check certainty. Back off and verify on-chain before retrying. |
TRANSACTION_ERROR_CODE_RPC_ERROR | Generic RPC failure. | Unknown | Check certainty. Verify on-chain before retrying. |
TRANSACTION_ERROR_CODE_CONNECTION_FAILED | Connection could not be established — transaction was likely NOT sent. | Likely no | Check certainty. Safe to retry if certainty is NOT_SUBMITTED. |
TRANSACTION_ERROR_CODE_REQUEST_FAILED | HTTP/transport layer request failed. | Unknown | Check certainty. Verify on-chain before retrying. |
TRANSACTION_ERROR_CODE_UNKNOWN | Unclassified error. | Unknown | Check certainty. Treat conservatively. |
TransactionSubmissionCertainty
The certainty field on a TransactionError object. Use this to determine whether it is safe to resubmit a transaction after an indeterminate error.
| Certainty | Value | Meaning | Handling |
|---|
TRANSACTION_SUBMISSION_CERTAINTY_NOT_SUBMITTED | 1 | 100% certain the transaction was NOT sent to the network. | Safe to rebuild and resubmit immediately. |
TRANSACTION_SUBMISSION_CERTAINTY_SUBMITTED | 2 | 100% certain the transaction WAS sent to the network. | Do not resubmit. Use MonitorTransaction to track the outcome. |
TRANSACTION_SUBMISSION_CERTAINTY_UNKNOWN_RESOLVABLE | 3 | Uncertain, but resolvable by waiting. | Wait until after blockhash_expiry_slot. Then query on-chain — if the transaction is not found, it is safe to recompile and resubmit. |
TRANSACTION_SUBMISSION_CERTAINTY_UNKNOWN | 4 | Uncertain and not easily resolvable. | Treat conservatively: wait for blockhash expiry, query on-chain, and only resubmit if the transaction is definitively absent. |
TRANSACTION_SUBMISSION_CERTAINTY_UNSPECIFIED | 0 | Not set (default). | Treat as UNKNOWN. |
blockhash_expiry_slot on the TransactionError object indicates when the transaction’s blockhash expires (approximately 150 slots after compilation). Once the blockhash has expired, any transaction that was broadcast but not confirmed is guaranteed to be dead — it is then safe to recompile and resubmit.