> ## Documentation Index
> Fetch the complete documentation index at: https://protochain.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Reference

> TransactionErrorCode values, retryability classification, and remediation guidance.

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.

<Note>
  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`
</Note>

### 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](/api-reference/transaction/compile-transaction) 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](/api-reference/transaction/compile-transaction) 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.

<Warning>
  `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.
</Warning>

| 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](/api-reference/transaction/monitor-transaction) 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`.                                                                                                                    |

<Note>
  `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.
</Note>
