FuelLabs/fuels-ts · error · FuelError

INSUFFICIENT_FUNDS

INSUFFICIENT_FUNDS

Error message

The account ${this.address} does not have enough base asset funds to cover the transaction execution.

What it means

After MAX_FUNDING_ATTEMPTS (5) rounds of fetching resources and re-estimating the fee, the account still cannot cover the base-asset requirement (transfer amount + gas/fee). The loop bails out and surfaces INSUFFICIENT_FUNDS so callers know the failure is a balance problem, not a network or encoding problem.

Source

Thrown at packages/account/src/account.ts:406

      const totalBaseAssetRequiredWithFee = requiredInBaseAsset.add(newFee);

      if (totalBaseAssetOnInputs.gt(totalBaseAssetRequiredWithFee)) {
        needsToBeFunded = false;
      } else {
        missingQuantities = [
          {
            amount: totalBaseAssetRequiredWithFee.sub(totalBaseAssetOnInputs),
            assetId: baseAssetId,
          },
        ];
      }

      fundingAttempts += 1;
    }

    // If the transaction still needs to be funded after the maximum number of attempts
    if (needsToBeFunded) {
      throw new FuelError(
        ErrorCode.INSUFFICIENT_FUNDS,
        `The account ${this.address} does not have enough base asset funds to cover the transaction execution.`
      );
    }

    request.updateState(chainId, 'funded', transactionSummary);

    await this.provider.validateTransaction(request);

    request.updatePredicateGasUsed(estimatedPredicates);

    const requestToReestimate = clone(request);
    if (addedSignatures) {
      Array.from({ length: addedSignatures }).forEach(() => requestToReestimate.addEmptyWitness());
    }

    if (!updateMaxFee) {
      return request;

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Check the base-asset balance before submitting: await account.getBalance() and compare against amount + estimated fee.
  2. Top up the account with base asset and retry.
  3. Consolidate dust UTXOs (account.cons ConsolidateCoins) to increase spendable UTXO coverage.
  4. Raise the gas limit / max-fee policy only if the issue is fee underestimation, then retry.

Example fix

// before
const tx = await account.transfer(target, 1_000_000);

// after
const baseAssetId = await account.provider.getBaseAssetId();
const bal = (await account.getBalances()).find(b => b.assetId === baseAssetId)?.amount ?? 0n;
if (bal < 1_000_000n + estimatedFee) {
  throw new Error(`need more base asset; have ${bal}`);
}
const tx = await account.transfer(target, 1_000_000);
Defensive patterns

Strategy: validation

Validate before calling

async function assertSufficientBaseAsset(
  account: Account,
  amount: bigint,
  estimatedFee: bigint
) {
  const baseAssetId = await account.provider.getBaseAssetId();
  const bal = (await account.getBalances()).find(b => b.assetId === baseAssetId)?.amount ?? 0n;
  if (bal < amount + estimatedFee) {
    throw new Error(`Insufficient base asset: have ${bal}, need ${amount + estimatedFee}`);
  }
}

Try / catch

try {
  await account.transfer(target, amount);
} catch (e) {
  if (e instanceof FuelError && e.code === ErrorCode.INSUFFICIENT_FUNDS) {
    // top up wallet or reduce amount, then retry once
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling account.fund / sendTransaction / transfer when the account's base-asset balance plus gathered UTXOs is less than amount + maxFee; fee spikes between attempts; too few UTXOs and consolidation disabled; dust-only balances.

Common situations: Insufficient funds in the wallet; gas price spike on a busy network; many small UTXOs hitting consolidation limits; wrong account used for the transfer; base asset ID mismatch.

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/5d18a4816bbc4912. Report an issue: GitHub.