nautechsystems/nautilus_trader · error
Approve authorization does not match the transaction call
Error message
Approve authorization does not match the transaction call
What it means
The client verifies that an authorized Approve operation exactly matches the signed transaction: `to` must be the authorized ERC20 token, value zero, and calldata must be the ABI-encoded approve(spender, amount) with the authorized router and amount. Mismatch is rejected to prevent signing calls beyond the granted approval authorization.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:2013
None => Ok(()),
Some(TransactionAuthorization::Wrap { weth }) => {
anyhow::ensure!(
to == *weth && !value.is_zero() && input == WETH9::depositCall::SELECTOR,
"Wrap authorization does not match the transaction call"
);
Ok(())
}
Some(TransactionAuthorization::Approve {
token,
router,
amount,
}) => {
let expected = ERC20::approveCall {
spender: *router,
amount: *amount,
}
.abi_encode();
anyhow::ensure!(
to == *token && value.is_zero() && input == expected,
"Approve authorization does not match the transaction call"
);
Ok(())
}
}
}
fn verification_decision<T>(
verified: &Verified<T>,
height_start: Option<u64>,
height_end: Option<u64>,
) -> ExecutionVerificationDecision {
ExecutionVerificationDecision {
read_class: verified.read.as_str(),
height_start,
height_end,
normalized_value_digest: verified.normalized_value_digest.to_string(),View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the call is `to == token`, `value == 0`, and input is abi_encode of ERC20::approveCall{spender: router, amount} matching the authorization exactly.
- Build the authorization and the transaction from the same source parameters so router/amount cannot diverge.
- Verify the token and router addresses in config match the intended chain deployments.
- If the approval intent changed, re-issue a new authorization rather than editing the transaction.
Example fix
// before: amount differs from authorization
let input = ERC20::approveCall { spender: router, amount: amount * 2 }.abi_encode();
verify_approve(auth, token, U256::zero(), &input)?; // mismatch
// after
let input = ERC20::approveCall { spender: auth.router, amount: auth.amount }.abi_encode();
verify_approve(auth, token, U256::zero(), &input)?; Defensive patterns
Strategy: validation
Validate before calling
let expected = ERC20::approveCall { spender: router, amount }.abi_encode();
assert!(value.is_zero() && to == token && input == expected, "approve call mismatch"); Type guard
fn is_approve_auth(auth: &TransactionAuthorization) -> Option<(Address, Address, U256)> {
if let TransactionAuthorization::Approve { token, router, amount } = auth { Some((*token, *router, *amount)) } else { None }
} Try / catch
match result { Err(e) if e.to_string().contains("Approve authorization does not match") => { reissue_authorization_and_retry(); } Ok(v) => v } Prevention
- Keep approval authorization and approve tx derived from one code path
- Never send value with approve calls
- Validate token/router addresses per chain before authorizing
When it happens
Trigger: prepare/sign path invoked with TransactionAuthorization::Approve but the transaction's `to` is not the authorized token, `value` is nonzero, or `input` is not exactly the encoded approveCall{spender: router, amount} — e.g. the approval amount or spender differs from what was authorized.
Common situations: Approval authorization generated for one router but the transaction targets a different spender; amount drift between plan creation and tx building; token address mismatch (wrong ERC20 in config); accidentally sending value with an approve call.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Router allowance {allowance} is below the swap amount {} for
- Wrap authorization does not match the transaction call
- Input token {} balance {balance} is below the swap amount {}
- Router {router} is not in the configured `router_addresses`
- Token {token} is not an input token in the configured `allow
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a14b98b1be927fcf.
Report an issue: GitHub.