Skip to main content
Version: 0.96.0

Error Reference

All CCIP SDK errors extend the base CCIPError class, providing structured error information including error codes, context, and recovery hints.

Error Structure

Every CCIPError includes:

TypeScript
interface CCIPError {
code: CCIPErrorCode // Machine-readable error code
message: string // Human-readable description
context: Record<string, unknown> // Structured context (IDs, addresses)
isTransient: boolean // True if retry may succeed
retryAfterMs?: number // Suggested retry delay
recovery?: string // Recovery suggestion
}

Using Error Utilities

Type Guard

TypeScript
import { CCIPError } from '@chainlink/ccip-sdk'

try {
await chain.getMessagesInTx(txHash)
} catch (error) {
if (CCIPError.isCCIPError(error)) {
console.log('Code:', error.code)
console.log('Context:', error.context)
console.log('Recovery:', error.recovery)
}
}

Transient Error Detection

TypeScript
import { CCIPError, isTransientError, withRetry } from '@chainlink/ccip-sdk'

// Check if error is transient
if (CCIPError.isCCIPError(error) && error.isTransient) {
// Safe to retry
await sleep(error.retryAfterMs ?? 5000)
}

// Or use built-in retry wrapper
const result = await withRetry(
() => chain.getMessageById(messageId),
{
maxRetries: 3,
initialDelayMs: 1000,
backoffMultiplier: 2,
maxDelayMs: 30000,
respectRetryAfterHint: true,
}
)

Error Serialization

TypeScript
import { formatErrorForLogging } from '@chainlink/ccip-sdk'

try {
await chain.sendMessage(...)
} catch (error) {
// Safe to log (handles non-enumerable properties)
console.error(JSON.stringify(formatErrorForLogging(error)))
}

Error Categories

Chain & Network Errors

ErrorCodeWhen ThrownRecovery
CCIPChainNotFoundErrorCHAIN_NOT_FOUNDChain selector/ID not in supported networksVerify chain is supported by CCIP
CCIPChainFamilyUnsupportedErrorCHAIN_FAMILY_UNSUPPORTEDChain family not implementedUse supported chain family (EVM, Solana, Aptos, Sui, TON)
CCIPChainFamilyMismatchErrorCHAIN_FAMILY_MISMATCHOperation across incompatible chain familiesEnsure source/dest chains are compatible
CCIPRpcNotFoundErrorRPC_NOT_FOUNDNo RPC endpoint configuredProvide RPC URL via --rpcs or environment

Transaction & Block Errors

ErrorCodeTransientWhen ThrownRecovery
CCIPTransactionNotFoundErrorTRANSACTION_NOT_FOUNDYesTransaction hash doesn't existVerify hash, wait for confirmation
CCIPBlockNotFoundErrorBLOCK_NOT_FOUNDYesBlock doesn't exist or not finalizedWait for block finalization
CCIPTransactionNotFinalizedErrorTRANSACTION_NOT_FINALIZEDYesTransaction not yet finalizedWait for finality

Message Errors

ErrorCodeTransientWhen ThrownRecovery
CCIPMessageNotFoundInTxErrorMESSAGE_NOT_FOUND_IN_TXYesTransaction has no CCIP messagesVerify correct transaction hash
CCIPMessageIdNotFoundErrorMESSAGE_ID_NOT_FOUNDYesMessage ID not found in searchProvide OnRamp hint, expand search range
CCIPMessageDecodeErrorMESSAGE_DECODE_FAILEDNoFailed to decode message dataCheck message format compatibility
CCIPMessageBatchIncompleteErrorMESSAGE_BATCH_INCOMPLETEYesNot all messages in batch foundRetry with larger search range
CCIPMessageInvalidErrorMESSAGE_INVALIDNoMessage structure is invalidVerify message fields

Lane & Routing Errors

ErrorCodeWhen ThrownRecovery
CCIPOffRampNotFoundErrorOFFRAMP_NOT_FOUNDNo OffRamp for source→dest laneVerify lane exists on CCIP
CCIPLaneNotFoundErrorLANE_NOT_FOUNDLane doesn't existCheck CCIP lane configuration
CCIPOnRampRequiredErrorONRAMP_REQUIREDOnRamp address needed but not providedProvide OnRamp address

Commit & Merkle Errors

ErrorCodeTransientWhen ThrownRecovery
CCIPCommitNotFoundErrorCOMMIT_NOT_FOUNDYesMessage not yet committedWait for DON to commit
CCIPMerkleRootMismatchErrorMERKLE_ROOT_MISMATCHNoCalculated root doesn't matchVerify all messages in batch
CCIPMerkleProofEmptyErrorMERKLE_PROOF_EMPTYNoNo proof elementsCheck message inclusion
CCIPMerkleTreeEmptyErrorMERKLE_TREE_EMPTYNoNo messages to hashVerify batch contains messages

Token Errors

ErrorCodeWhen ThrownRecovery
CCIPTokenNotFoundErrorTOKEN_NOT_FOUNDToken address invalid or not foundVerify token address
CCIPTokenNotConfiguredErrorTOKEN_NOT_CONFIGUREDToken not configured in registryCheck TokenAdminRegistry
CCIPTokenNotInRegistryErrorTOKEN_NOT_IN_REGISTRYToken not in admin registryRegister token with CCIP
CCIPTokenDecimalsInsufficientErrorTOKEN_DECIMALS_INSUFFICIENTToken decimals too low for transferUse different token or adjust amount
CCIPTokenPoolChainConfigNotFoundErrorTOKEN_REMOTE_NOT_CONFIGUREDRemote chain not configured for tokenConfigure remote chain in pool

Execution Errors

ErrorCodeWhen ThrownRecovery
CCIPExecTxRevertedErrorEXEC_TX_REVERTEDManual execution transaction revertedCheck gas limit, receiver contract
CCIPExecTxNotConfirmedErrorEXEC_TX_NOT_CONFIRMEDExecution tx didn't confirmIncrease gas, retry
CCIPReceiptNotFoundErrorRECEIPT_NOT_FOUNDExecution receipt not foundWait for execution, check offRamp

Attestation Errors (USDC/LBTC)

ErrorCodeTransientWhen ThrownRecovery
CCIPUsdcAttestationErrorUSDC_ATTESTATION_FAILEDYesUSDC attestation service errorRetry after delay
CCIPLbtcAttestationErrorLBTC_ATTESTATION_ERRORYesLBTC attestation service errorRetry after delay
CCIPLbtcAttestationNotFoundErrorLBTC_ATTESTATION_NOT_FOUNDYesLBTC attestation not yet availableWait and retry
CCIPLbtcAttestationNotApprovedErrorLBTC_ATTESTATION_NOT_APPROVEDYesLBTC attestation pending approvalWait for approval

Wallet & Signer Errors

ErrorCodeWhen ThrownRecovery
CCIPWalletInvalidErrorWALLET_INVALIDWallet not a valid signerProvide ethers Signer or use viemWallet(client) wrapper
CCIPWalletNotSignerErrorWALLET_NOT_SIGNERWallet can't sign transactionsUse wallet with signing capability
CCIPInsufficientBalanceErrorINSUFFICIENT_BALANCEInsufficient funds for transactionAdd funds to wallet

Version Errors

ErrorCodeWhen ThrownRecovery
CCIPVersionUnsupportedErrorVERSION_UNSUPPORTEDCCIP version not supportedUse supported version (v1.2, v1.5, v1.6)
CCIPVersionFeatureUnavailableErrorVERSION_FEATURE_UNAVAILABLEFeature not available in versionUpgrade to newer CCIP version
CCIPHasherVersionUnsupportedErrorHASHER_VERSION_UNSUPPORTEDHasher not implemented for versionUse supported version

HTTP & API Errors

ErrorCodeTransientWhen ThrownRecovery
CCIPHttpErrorHTTP_ERRORYesHTTP request failedRetry with backoff
CCIPTimeoutErrorTIMEOUTYesOperation timed outIncrease timeout, retry
CCIPApiClientNotAvailableErrorAPI_CLIENT_NOT_AVAILABLENoAPI client not configuredInitialize CCIPAPIClient

Solana-Specific Errors

ErrorCodeWhen ThrownRecovery
CCIPSolanaComputeUnitsExceededErrorSOLANA_COMPUTE_UNITS_EXCEEDEDTransaction exceeded compute unitsIncrease compute units in extraArgs
CCIPSolanaLookupTableNotFoundErrorSOLANA_LOOKUP_TABLE_NOT_FOUNDAddress lookup table not foundVerify router configuration
CCIPSplTokenInvalidErrorTOKEN_INVALID_SPLInvalid SPL tokenVerify token is valid SPL token

Aptos-Specific Errors

ErrorCodeWhen ThrownRecovery
CCIPAptosAddressInvalidErrorADDRESS_INVALID_APTOSInvalid Aptos address formatUse valid Aptos address
CCIPAptosExtraArgsV2RequiredErrorEXTRA_ARGS_APTOS_V2_REQUIREDEVMExtraArgsV2 required for AptosUse EVMExtraArgsV2 with allowOutOfOrderExecution

Viem Adapter Errors

ErrorCodeWhen ThrownRecovery
CCIPViemAdapterErrorVIEM_ADAPTER_ERRORViem client misconfiguredEnsure chain and account are defined on client

Handling Patterns

Basic Error Handling

TypeScript
import { CCIPError, CCIPErrorCode } from '@chainlink/ccip-sdk'

try {
const requests = await chain.getMessagesInTx(txHash)
} catch (error) {
if (!CCIPError.isCCIPError(error)) {
throw error // Re-throw non-CCIP errors
}

switch (error.code) {
case CCIPErrorCode.TRANSACTION_NOT_FOUND:
console.log('Transaction not found - verify the hash')
break
case CCIPErrorCode.MESSAGE_NOT_FOUND_IN_TX:
console.log('No CCIP messages in this transaction')
break
default:
console.log('Error:', error.message)
if (error.recovery) {
console.log('Recovery:', error.recovery)
}
}
}

Retry with Transient Errors

TypeScript
import { CCIPError, withRetry } from '@chainlink/ccip-sdk'

async function getMessageWithRetry(chain, messageId) {
return withRetry(
async () => {
try {
return await chain.getMessageById(messageId)
} catch (error) {
// Convert to CCIPError if needed
throw CCIPError.from(error)
}
},
{
maxRetries: 5,
initialDelayMs: 2000,
backoffMultiplier: 2,
maxDelayMs: 60000,
respectRetryAfterHint: true,
logger: console,
}
)
}

Manual Execution Error Recovery

TypeScript
import {
CCIPError,
CCIPErrorCode,
calculateManualExecProof,
} from '@chainlink/ccip-sdk'

try {
const proof = calculateManualExecProof(
messagesInBatch,
lane,
messageId,
expectedMerkleRoot
)
} catch (error) {
if (!CCIPError.isCCIPError(error)) throw error

switch (error.code) {
case CCIPErrorCode.MERKLE_ROOT_MISMATCH:
console.log('Merkle root mismatch')
console.log('Expected:', error.context.expected)
console.log('Calculated:', error.context.calculated)
console.log('Check if all messages in batch are included')
break

case CCIPErrorCode.MESSAGE_NOT_IN_BATCH:
console.log('Message not in batch')
console.log('Message ID:', error.context.messageId)
console.log('Verify sequence number range')
break

case CCIPErrorCode.MESSAGE_BATCH_INCOMPLETE:
console.log('Batch incomplete - retry with larger range')
break
}
}

Transient Error Codes

These errors may succeed on retry:

TypeScript
const TRANSIENT_CODES = [
'BLOCK_NOT_FOUND',
'TRANSACTION_NOT_FOUND',
'BLOCK_TIME_NOT_FOUND',
'TRANSACTION_NOT_FINALIZED',
'MESSAGE_NOT_FOUND_IN_TX',
'MESSAGE_ID_NOT_FOUND',
'MESSAGE_BATCH_INCOMPLETE',
'COMMIT_NOT_FOUND',
'RECEIPT_NOT_FOUND',
'USDC_ATTESTATION_FAILED',
'LBTC_ATTESTATION_ERROR',
'LBTC_ATTESTATION_NOT_FOUND',
'HTTP_ERROR',
'TIMEOUT',
'SOLANA_LOOKUP_TABLE_NOT_FOUND',
'SOLANA_REF_ADDRESSES_NOT_FOUND',
]