nautechsystems/nautilus_trader · critical · anyhow::Error
Binance Futures account state request failed: {e}
Error message
Binance Futures account state request failed: {e} What it means
refresh_account_state bails when the HTTP query_account call fails, wrapping the underlying transport/API error in a message that duplicates the log::error line above it. This runs during the execution client's connect flow, so the failure prevents the client from finishing connection and no orders can be managed until it succeeds. The meaningful detail is inside the wrapped {e}: the Binance error code for auth, timestamp, or permission problems.
Source
Thrown at crates/adapters/binance/src/futures/execution.rs:469
account_id,
account_type,
balances,
margins,
true, // reported
UUID4::new(),
ts_now,
ts_now,
None, // base currency
)
.with_info(info)
}
async fn refresh_account_state(&self) -> anyhow::Result<AccountState> {
let account_info = match self.http_client.query_account().await {
Ok(info) => info,
Err(e) => {
log::error!("Binance Futures account state request failed: {e}");
anyhow::bail!("Binance Futures account state request failed: {e}");
}
};
Ok(self.create_account_state(&account_info))
}
fn update_account_state(&self) {
let http_client = self.http_client.clone();
let account_id = self.core.account_id;
let account_type = self.core.account_type;
let bnfcr_currency = self.config.bnfcr_currency;
let emitter = self.emitter.clone();
let clock = self.clock;
self.spawn_task("query_account", async move {
let account_info = http_client
.query_account()
.awaitView on GitHub (pinned to a4b06ed870)
Solutions
- Read the wrapped error code: -2015 invalid key/permissions, -1021 timestamp outside recvWindow, -1003 IP ban/rate limit
- Verify the api_key/api_secret pair and that USD-M or COIN-M futures access is enabled for the key
- Confirm the environment (Live/Testnet/Demo) matches the credentials and base URL
- Sync the system clock via NTP and retry connect with backoff; check network egress to the exchange host
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight before connect: credentials resolvable and clock in sync
fn preflight_ok() -> bool {
let key_missing = std::env::var("BINANCE_API_KEY").map_or(true, |v| v.is_empty());
// optionally GET /fapi/v1/time and compare to local clock; |delta| should be far under recvWindow (default 5s)
!key_missing
} Try / catch
// account-state failures surface from the connect flow; retry with backoff, treat
// auth codes (-2015) as fatal, transient network as retryable
const MAX: u32 = 3;
for attempt in 1..=MAX {
match client.connect().await {
Ok(()) => break,
Err(e) if attempt < MAX && !e.to_string().contains("-2015") => {
tokio::time::sleep(std::time::Duration::from_secs(2u64.pow(attempt))).await;
}
Err(e) => return Err(e),
}
} Prevention
- Store keys via the project's secret-resolution path (env/registry), never inline
- Enable futures permissions on the API key before first connect
- Run NTP on trading hosts; monitor clock delta against /fapi/v1/time
- Pin environment (Live/Testnet/Demo) in one config source
When it happens
Trigger: Connecting the Binance Futures execution client with invalid or futures-disabled API credentials (-2015), IP-restricted keys used off the allowlist, clock skew beyond recvWindow (-1021), network outage, or a testnet/live environment mismatch between keys and base URL.
Common situations: First live run with keys that lack futures permissions; testnet keys pointed at api.binance.com; NTP drift on the host; firewall blocking egress to the exchange; read-only keys where balances/trading info is restricted.
Related errors
- A BacktestNode is required for the bars_with_fills chart
- Authentication failed: {e}
- Timeout waiting for account {account_id} to be registered af
- run_config_id is required when a BacktestNode is provided
- failed to request AX whoami
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/ac595e1143d4f4fa.
Report an issue: GitHub.