nautechsystems/nautilus_trader · error
Input token {} balance {balance} is below the swap amount {}
Error message
Input token {} balance {balance} is below the swap amount {} What it means
Pre-trade check that reads balanceOf(plan.token_in, wallet_address) via the ERC-20 contract and rejects when the wallet holds less of the input token than plan.amount_in. It runs after the allowance check so the caller learns about funding before the router could pull tokens.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:2428
let allowance = erc20_contract
.allowance(&plan.token_in, &executor.wallet_address, &plan.router)
.await?;
if allowance < plan.amount_in {
anyhow::bail!(
"Router allowance {allowance} is below the swap amount {} for input token {}; approve the router explicitly before submitting",
plan.amount_in,
plan.token_in
);
}
let balance = erc20_contract
.balance_of(&plan.token_in, &executor.wallet_address)
.await?;
if balance < plan.amount_in {
anyhow::bail!(
"Input token {} balance {balance} is below the swap amount {}",
plan.token_in,
plan.amount_in
);
}
Ok(())
}
/// Converts a base-denominated order quantity into raw token units with exact integer
/// scaling by the base token decimals.
///
/// `Quantity::raw` is scaled to the greater of its declared precision and `FIXED_PRECISION`;
/// token amounts are scaled to the token's decimals. Quantities not exactly representable in
/// token units are rejected rather than rounded.
fn quantity_to_raw_amount(quantity: Quantity, decimals: u8) -> anyhow::Result<U256> {
if quantity.is_zero() {
anyhow::bail!("Order quantity must be positive");View on GitHub (pinned to 2114cf6f76)
Solutions
- Transfer plan.token_in of at least plan.amount_in to the configured wallet_address on the correct chain
- Confirm wallet_address in the client config is the account that holds the funds and matches the signer key
- Retry after checking the balance in a block explorer to confirm the transfer landed (watch for pending txs)
- Reduce the order/swap size to the available balance
Example fix
// before: order sized 1000 USDC but wallet holds 250 USDC let plan = build_swap_plan(amount_in: qty_to_raw(1000, 6)); // after: size the swap from the live balance let balance = erc20.balance_of(&token_in, &wallet).await?; let amount_in = balance.min(desired_amount_in); // never exceeds holdings
Defensive patterns
Strategy: validation
Validate before calling
// Size swaps from the live balance
let balance = erc20.balance_of(&token_in, &wallet).await?;
anyhow::ensure!(balance >= amount_in, "wallet short of {token_in}: {balance} < {amount_in}"); Type guard
fn has_sufficient_balance(balance: U256, amount_in: U256) -> bool { balance >= amount_in } Try / catch
// Terminal precondition: do not retry after funding mid-flight; fund, wait for the
// transfer to confirm, then rebuild the plan with a fresh quote.
if let Err(e) = execute_swap(plan).await {
if e.to_string().contains("balance") { notify_treasury(&e.to_string()); }
return Err(e);
} Prevention
- Monitor the execution wallet's token balances and alert below a funding threshold
- Give each strategy its own wallet or reserve buffer so concurrent orders do not race one balance
- Re-check balance after any deposit before sizing orders
When it happens
Trigger: Submitting a swap with plan.amount_in greater than the wallet's token balance: unfunded or underfunded wallet, balance consumed by concurrent strategies on the same wallet, gas/fees or prior trades reducing the balance, or wallet_address configured for a different account than the one holding funds.
Common situations: New environment where the execution wallet was never funded; sharing one wallet across strategies so balances race; the wallet address in config drifts from the account actually holding tokens (also caught indirectly by the signer check at connect); staked/locked balances that are not transferrable.
Related errors
- Router allowance {allowance} is below the swap amount {} for
- No deployed bytecode at {description} address {address}
- No pool profiler for {instrument_id}; an active data subscri
- Order quantity must be positive
- Swap quote output amount {amount} is not a positive output
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/49538ad31a6aa87e.
Report an issue: GitHub.