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

  1. Send an ERC-20 approve() transaction to the input token granting the router at least amount_in, then retry the swap
  2. Verify the allowance is being granted to the exact router address the plan uses (not an old router)
  3. Check the allowance again after approval confirms (account for already-consumed allowances)
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/7691f927561e4a3a. Report an issue: GitHub.