Skip to main content
This page has been updated for Wallets SDK V1. If you are using the previous version, see the previous version of this page or the V1 migration guide.
Sometimes transactions fail. This guide outlines common failure reasons and provides tools to help you identify the underlying causes.
Reverted transactions are marked as “failed” and won’t be executed. There is no auto-retry mechanism for failed transactions; you must manually resubmit them if needed.

Common Error Types

Transaction errors typically fall into two categories: validation failures and execution failures.

Validation Errors

Validation errors occur when the provided transaction data is invalid. These errors commonly relate to invalid data (e.g., signature) during transaction approval. Common issues include:
  • Malformed signatures
  • Invalid signatures (e.g., from an unauthorized wallet)
  • Insufficient signer permissions for transaction approval
An example of a validation error:
"error": {
  "reason": "execution_reverted",
  "message": "Execution reverted, see 'revert' for details",
  "revert": {
    "type": "wallet_authorization",
    "reason": "Invalid signature",
    "reasonData": "AA24",
    "simulationLink": "https://www.tdly.co/shared/simulation/e61be684-5359-48a6-9173-349cd44c6e6c"
  }
}
Troubleshooting steps:
  • Verify the transaction signer is valid
  • Confirm you’re signing the correct message data
  • Verify the signing private key matches the signer wallet

Execution Errors

Execution errors occur when a transaction is reverted during runtime. These typically relate to the calls provided during transaction creation. Common causes include:
  • Another transaction with the same call was executed already
  • State changes between transaction creation and execution (e.g. asset price updated exceeding slippage allowance)
The Crossmint API typically provides specific revert reasons:
"error": {
  "reason": "execution_reverted",
  "message": "Execution reverted, see 'revert' for details",
  "revert": {
    "type": "contract_call",
    "reason": "ERC20: transfer amount exceeds balance",
    "simulationLink": "https://www.tdly.co/shared/simulation/18b810b5-33b6-4091-a3a1-d7318f73bbec"
  }
}
Troubleshooting:
  • Review the simulation to understand the revert cause
  • Check for similar previous transactions
  • Attempt to resubmit with the same parameters

Wallet Errors

WalletNotAvailableError

Thrown by getWallet() when no wallet exists for the given parameters. This is expected in the get-then-create pattern where you first attempt to retrieve a wallet and fall back to creating one.
import { useWallet } from "@crossmint/client-sdk-react-ui";
import { WalletNotAvailableError } from "@crossmint/wallets-sdk";

const { getWallet, createWallet } = useWallet();

try {
    const wallet = await getWallet({ chain: "base-sepolia" });
} catch (error) {
    if (error instanceof WalletNotAvailableError) {
        // No wallet exists yet — create one
        const wallet = await createWallet({
            chain: "base-sepolia",
            recovery: { type: "email", email: "user@example.com" },
        });
    }
}
In previous SDK versions, getOrCreateWallet() handled this automatically. In V1, wallet retrieval and creation are separate operations. See the migration guide for details.

Common Pitfalls

These are frequent sources of confusion when working with the V1 SDK.

Read-only wallet from getWallet()

getWallet() returns a wallet with no active signer unless a device signer is found locally. Calling send(), approve(), or addSigner() on a read-only wallet throws an error. Fix: Call wallet.useSigner() to activate a signer before performing signing operations, or rely on automatic device signer initialization on the client side.
const wallet = await getWallet({ chain: "base-sepolia" });

// wallet.signer may be undefined — check before signing
if (wallet.signer == null) {
    await wallet.useSigner({ type: "passkey" });
}

await wallet.send("0x...", "usdc", "1.0");

useSigner() does not accept locator strings

In V1, useSigner() only accepts signer config objects. Passing a locator string (e.g., "evm-keypair:0x...") results in a type error.
// ❌ Old — no longer works
await wallet.useSigner("evm-keypair:0xABC...");

// ✅ New — pass a config object
await wallet.useSigner({ type: "external-wallet", address: "0xABC..." });

getWallet() parameter mismatch between client and server

getWallet() has different signatures on client and server. Using the wrong one throws an error.
  • Client-side: getWallet({ chain: "base-sepolia" }) — pass wallet args directly. Passing a walletLocator string as the first argument throws.
  • Server-side: getWallet("0xWalletAddress", { chain: "base-sepolia" }) — requires a walletLocator string as the first parameter. Omitting it throws: "getWallet on server side requires a walletLocator parameter."

Client-side input validation errors

The V1 SDK validates inputs before making API calls, failing fast with descriptive errors:
ErrorThrown byCause
InvalidAddressErrorwallet.send()Invalid to address format for the chain (EVM: 0x + 40 hex chars, Solana: base58, Stellar: G + 55 alphanumeric)
InvalidChainErrorcreateWallet(), getWallet()Unrecognized chain name
InvalidAmountErrorwallet.send()Zero, negative, Infinity, or NaN amount

Email and phone signers cannot be added via addSigner()

addSigner() does not support email or phone signer types. These can only be configured as recovery signers during wallet creation. Attempting to add them throws a backend error.
// ❌ Not supported
await wallet.addSigner({ type: "email", email: "user@example.com" });

// ✅ Use email as recovery signer during wallet creation instead
const wallet = await createWallet({
    chain: "base-sepolia",
    recovery: { type: "email", email: "user@example.com" },
});

Solana wallets fall back to recovery signer

Device signers are not currently supported for Solana. Solana wallets automatically use the recovery signer for signing, which involves higher friction (OTP verification).

Other Errors

If you encounter transaction failures without error details or receive no error message, there may be an issue with the Crossmint infrastructure. First, check the status page to verify API availability and try again later. If the problem continues, please contact our support team.

Debugging

The Crossmint API simulates all transactions before submitting them onchain. Failed simulations prevent onchain execution. In most cases, the transaction will fail during the simulation. If that’s the case, you can use Tenderly to inspect the details. Otherwise, you can use a block explorer to inspect the transaction.

Tenderly

Tenderly is an EVM transaction tracing software. For each transaction that is failed during simulation, Crossmint API includes a link to the Tenderly simulation.

Block Explorer

If the transaction was included onchain, you can check its status using a block explorer.