nautechsystems/nautilus_trader · error
Signer not initialized; connect the client first
Error message
Signer not initialized; connect the client first
What it means
This error is raised in prepare_swap (called from submit_order) when the blockchain execution client has no signer configured. A swap transaction cannot be signed or submitted without a signer (private key/wallet), so the client fails fast before building the swap call. Call client.connect(...) with signer credentials before submitting orders that require swaps.
Solutions
- Call client.connect(...) with valid signer credentials before submit_order
- Verify the client config includes a private key, keystore, or KMS signer reference
- Check that connect() succeeded and did not swallow an error leaving signer unset
- Log/inspect whether the signer was dropped or reset between construction and submission
Example fix
// before let client = ExecutionClient::new(config); client.submit_order(order).await?; // after let client = ExecutionClient::new(config); client.connect(signer_credentials).await?; assert!(client.has_signer()); client.submit_order(order).await?;
Defensive patterns
Strategy: validation
Validate before calling
if !client.has_signer() {
anyhow::bail!("call client.connect(credentials) before submit_order");
} Type guard
fn signer_ready(client: &ExecutionClient) -> bool {
client.has_signer()
} Prevention
- Always call connect() immediately after client construction in setup code
- Add an integration smoke test that submits a tiny order on a testnet
- Assert signer presence at application startup, not at trade time
When it happens
Trigger: Calling submit_order (which reaches prepare_swap) on a client constructed without a signer, or after the signer was removed/reset; the client reached ensure_transaction_ready but self.signer is still None.
Common situations: Forgetting to call connect() before submit_order; constructing the client in read-only/market-data mode and then trading; a config file missing the private key/keystore entry; signer initialization failing silently earlier and leaving signer None.
Related errors
- Execution verification ledger is not initialized
- Finalized Swap base amount
- Finalized Swap has no calculated trade information
- Finalized Swap input
- Finalized Swap input
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0944dd8758ffc988.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1718
"No `quote_spend_limits` entry for BUY token pair {token_in} -> {token_out}"
)
})?;
if amount_in > ceiling.max_amount {
anyhow::bail!(
"BUY quote amount {amount_in} exceeds the configured `quote_spend_limits` maximum {} for {token_in} -> {token_out}",
ceiling.max_amount
);
}
(amount_in, base_amount)
}
};
let min_amount_out = derive_min_amount_out(quoted_amount_out, slippage_bps)?;
self.ensure_transaction_ready(TransactionPurpose::Swap)?;
if self.signer.is_none() {
anyhow::bail!("Signer not initialized; connect the client first");
}
let pool_address = pool.address;
let factory = self.uniswap_v3_factory()?;
anyhow::ensure!(
pool.dex.factory == factory,
"Pool {instrument_id} references factory {}, expected registered factory {factory}",
pool.dex.factory
);
Ok(SwapPlan {
order: order.clone(),
pool,
quote_currency,
instrument_id,
pool_address,
router: self.router_addresses[0],
factory,View on GitHub (pinned to 18893faf8b)