nautechsystems/nautilus_trader · error
Router allowance {} is below the swap amount {} for input to
Error message
Router allowance {} is below the swap amount {} for input token {}; approve the router explicitly before submitting What it means
Before submitting a swap, the client verifies the wallet's ERC-20 allowance to the router for the input token. This error is thrown when the allowance is less than amount_in: the router would fail to pull the required tokens, so the swap is rejected with instructions to approve explicitly first.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:5154
}
.abi_encode();
let allowance = required_verification(
executor
.verification
.verify_decoded_call(
None,
&plan.token_in,
U256::ZERO,
&allowance_call,
block,
|result| ERC20::allowanceCall::abi_decode_returns(result).map_err(Into::into),
)
.await,
"swap input allowance",
)?;
if allowance.value < plan.amount_in {
anyhow::bail!(
"Router allowance {} is below the swap amount {} for input token {}; approve the router explicitly before submitting",
allowance.value,
plan.amount_in,
plan.token_in
);
}
decisions.push(verification_decision(&allowance, Some(block), Some(block)));
let balance_call = ERC20::balanceOfCall {
account: executor.wallet_address,
}
.abi_encode();
let balance = required_verification(
executor
.verification
.verify_decoded_call(
None,
&plan.token_in,View on GitHub (pinned to 18893faf8b)
Solutions
- Send an ERC-20 approve() transaction to the input token granting the router at least amount_in, then retry the swap
- Verify the allowance is being granted to the exact router address the plan uses (not an old router)
- Check the allowance again after approval confirms (account for already-consumed allowances)
- Consider an unlimited approval if recurring swaps on the same router are intended (weigh security trade-offs)
Example fix
// before: swapping without checking allowance
submit_swap(plan).await?;
// after: approve router first when allowance is short
if allowance < plan.amount_in {
token.approve(router, plan.amount_in).send().await?;
}
submit_swap(plan).await?; Defensive patterns
Strategy: validation
Validate before calling
let allowance = token.allowance(wallet, router).await?;
if allowance < plan.amount_in {
token.approve(router, plan.amount_in.max(allowance)).send().await?;
} Try / catch
match res {
Err(e) if e.to_string().contains("allowance") => {
token.approve(plan.router, plan.amount_in).send().await?;
submit_swap(plan).await?;
}
other => other?,
} Prevention
- Always approve the exact router address the plan references
- Check allowance before every swap when using exact-amount approvals
- Re-approve after router upgrades or address changes
- Prefer allowance checks in the pre-trade checklist
When it happens
Trigger: Submitting a swap plan where the input token's router allowance (checked via the token contract's allowance() call) is below plan.amount_in — e.g. no prior approval, an approval for a smaller amount, or an approval granted to a different router address.
Common situations: First swap of a token without approving the router; a previous swap consumed a limited allowance; the router address changed after an upgrade so the old approval no longer applies; approvals set to exact amounts in earlier trades.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- Router allowance {allowance} is below the swap amount {} for
- Input token {} balance {} is below the swap amount {}
- No deployed bytecode at {description} address {address}
- Input token {} balance {balance} is below the swap amount {}
- HyperSync parsing of swap event is not defined in this dex:
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7691f927561e4a3a.
Report an issue: GitHub.