Skip to main content
Protochain returns structured errors that tell you whether to retry, rebuild, or check on-chain state. The patterns below cover the most common scenarios.
For the full list of error codes with retryability classifications and remediation actions, see the Error Reference.

Pattern 1: Checking if an error is retryable

Inspect the TransactionErrorCode on a SubmitTransaction error to determine whether you can retry the same transaction, need to rebuild it, or need to check on-chain state. Error codes fall into three categories (see Error Reference):
  • Temporary (INSUFFICIENT_FUNDS, ACCOUNT_IN_USE, WOULD_EXCEED_BLOCK_LIMIT) — transaction was NOT sent; retry the same transaction
  • Permanent (INVALID_TRANSACTION, INVALID_SIGNATURE, PROGRAM_ERROR, etc.) — transaction was NOT sent; do not retry without rebuilding
  • Indeterminate (TIMEOUT, NETWORK_ERROR, RATE_LIMITED, etc.) — unknown whether the transaction was sent; check certainty (see Pattern 2)

Pattern 2: Handling indeterminate submission (TransactionSubmissionCertainty)

Indeterminate errors are the trickiest case — you don’t know if the transaction was broadcast. The certainty field on the TransactionError tells you how to proceed.
  • CERTAINTY_SUBMITTED — the transaction was sent; use GetTransaction or MonitorTransaction to poll for the result
  • CERTAINTY_NOT_SUBMITTED — the transaction was not sent; safe to retry or resubmit
  • CERTAINTY_UNKNOWN_RESOLVABLE — uncertain but resolvable; wait until after blockhash_expiry_slot, then query on-chain — if not found, safe to recompile and resubmit
  • CERTAINTY_UNKNOWN — uncertain and not easily resolvable; treat conservatively, wait for blockhash expiry, query on-chain before deciding to resubmit

Pattern 3: Handling program execution failures

TRANSACTION_ERROR_CODE_PROGRAM_ERROR means the on-chain program rejected the instruction. The error code itself is generic — call GetTransaction with the transaction signature to retrieve the detailed meta_error_message from the on-chain logs.

Pattern 4: Handling expired blockhash

Compiled transactions expire after approximately 150 slots (~60 seconds). TRANSACTION_ERROR_CODE_BLOCKHASH_EXPIRED means the transaction is stale and cannot be submitted. You must recompile — not just re-sign — to get a fresh blockhash.