nautechsystems/nautilus_trader · error
Router allowance {allowance} is below the swap amount {} for
Error message
Router allowance {allowance} is below the swap amount {} for input token {}; approve the router explicitly before submitting What it means
Pre-trade check that reads the ERC-20 allowance of the configured wallet for the swap router on the input token, and rejects when allowance < plan.amount_in. The blockchain execution client deliberately never auto-approves, because an on-chain approval is a state-changing transaction that costs gas and widens token access; the caller must approve the router explicitly.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:2416
] {
let code = executor.http_rpc_client.get_code(&address).await?;
if code.is_empty() {
anyhow::bail!("No deployed bytecode at {description} address {address}");
}
}
let erc20_contract = Erc20Contract::new_with_timeout(
executor.http_rpc_client.clone(),
Some(EXECUTION_RPC_TIMEOUT_SECS),
true,
);
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
);
}
View on GitHub (pinned to 2114cf6f76)
Solutions
- Send an ERC-20 approve(plan.router, amount >= plan.amount_in) transaction from the configured wallet for plan.token_in, then retry the swap
- Grant a larger or max allowance if frequent swaps are expected, accepting the standard approval-risk tradeoff
- Verify the approval is on the same chain and for the exact router address in the SwapPlan
- Reduce plan.amount_in to fit within the existing allowance
Example fix
// before: no approval, swap fails precheck with
// 'Router allowance 0 is below the swap amount ...'
// after: approve the router once from the wallet
let erc20 = Erc20Contract::new(http_rpc_client.clone());
let _receipt = erc20
.approve(&token_in, &router, U256::MAX)
.await?; // or the exact swap amount Defensive patterns
Strategy: validation
Validate before calling
// Before submitting, confirm allowance >= amount_in and approve if needed
let allowance = erc20.allowance(&token_in, &wallet, &router).await?;
if allowance < amount_in {
erc20.approve(&token_in, &router, amount_in).await?; // explicit approval tx
} Type guard
fn has_sufficient_allowance(allowance: U256, amount_in: U256) -> bool { allowance >= amount_in } Try / catch
match execute_swap(plan).await {
Err(e) if e.to_string().contains("Router allowance") => {
// deterministic precondition: approve, then retry once with a fresh plan
approve_router(&plan.token_in, &plan.router, plan.amount_in).await?;
execute_swap(plan).await
}
other => other,
} Prevention
- Approve the router once during deployment rather than per swap
- Track granted allowances alongside wallet state and re-approve before they are exhausted
- Approve on the same chain and for the exact router address the plan will use
When it happens
Trigger: Submitting a swap when allowance(owner=wallet_address, spender=plan.router) on plan.token_in is zero or below plan.amount_in: first-ever swap with a token, a previously granted exact-size allowance consumed by earlier swaps, an allowance granted to a different router address than plan.router, or an increased order size beyond the approved amount.
Common situations: Fresh wallet or fresh deployment with no approvals yet; switching the plan to a new router (aggregator/uniswap version) while approvals still point at the old one; allowance used down by repeated swaps; approval performed on the wrong chain or for the wrong token.
Related errors
- Input token {} balance {balance} is below the swap amount {}
- 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/5850c6dfd47cff36.
Report an issue: GitHub.