{"record":{"id":"7691f927561e4a3a","repo":"nautechsystems/nautilus_trader","slug":"router-allowance-is-below-the-swap-amount-fo","errorCode":null,"errorMessage":"Router allowance {} is below the swap amount {} for input token {}; approve the router explicitly before submitting","messagePattern":"Router allowance (.+?) is below the swap amount (.+?) for input token (.+?); approve the router explicitly before submitting","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":5154,"sourceCode":"    }\n    .abi_encode();\n    let allowance = required_verification(\n        executor\n            .verification\n            .verify_decoded_call(\n                None,\n                &plan.token_in,\n                U256::ZERO,\n                &allowance_call,\n                block,\n                |result| ERC20::allowanceCall::abi_decode_returns(result).map_err(Into::into),\n            )\n            .await,\n        \"swap input allowance\",\n    )?;\n\n    if allowance.value < plan.amount_in {\n        anyhow::bail!(\n            \"Router allowance {} is below the swap amount {} for input token {}; approve the router explicitly before submitting\",\n            allowance.value,\n            plan.amount_in,\n            plan.token_in\n        );\n    }\n    decisions.push(verification_decision(&allowance, Some(block), Some(block)));\n\n    let balance_call = ERC20::balanceOfCall {\n        account: executor.wallet_address,\n    }\n    .abi_encode();\n    let balance = required_verification(\n        executor\n            .verification\n            .verify_decoded_call(\n                None,\n                &plan.token_in,","sourceCodeStart":5136,"sourceCodeEnd":5172,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L5136-L5172","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before: swapping without checking allowance\nsubmit_swap(plan).await?;\n// after: approve router first when allowance is short\nif allowance < plan.amount_in {\n    token.approve(router, plan.amount_in).send().await?;\n}\nsubmit_swap(plan).await?;","handlingStrategy":"validation","validationCode":"let allowance = token.allowance(wallet, router).await?;\nif allowance < plan.amount_in {\n    token.approve(router, plan.amount_in.max(allowance)).send().await?;\n}","typeGuard":null,"tryCatchPattern":"match res {\n    Err(e) if e.to_string().contains(\"allowance\") => {\n        token.approve(plan.router, plan.amount_in).send().await?;\n        submit_swap(plan).await?;\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["blockchain","erc20","allowance","swap"],"backgroundTag":"insufficient-permissions","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}