nautechsystems/nautilus_trader · critical
Signer address {} derived from '{}' does not match configure
Error message
Signer address {} derived from '{}' does not match configured wallet address {} What it means
At connect(), the signer private key is read from the environment variable named by signer_private_key_env, parsed, and its derived address must equal the configured wallet_address. A mismatch aborts the connection: the system refuses to trade with a key that is not the account the rest of the configuration (balances, allowances, wallet address) refers to.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:2790
}
// Load the signer key from the configured environment variable; the key is never
// logged, serialized, or stored in configuration
let private_key = std::env::var(&self.config.signer_private_key_env).map_err(|_| {
anyhow::anyhow!(
"Signer private key environment variable '{}' is not set",
self.config.signer_private_key_env
)
})?;
let signer = PrivateKeySigner::from_str(private_key.trim()).map_err(|_| {
anyhow::anyhow!(
"Signer private key in '{}' is not a valid hex private key",
self.config.signer_private_key_env
)
})?;
if signer.address() != self.wallet_address {
anyhow::bail!(
"Signer address {} derived from '{}' does not match configured wallet address {}",
signer.address(),
self.config.signer_private_key_env,
self.wallet_address
);
}
self.signer = Some(signer);
if self.cache.has_database()
&& let Err(e) = self.reconcile_unresolved_execution().await
{
self.signer = None;
return Err(e);
}
if let Err(e) = self.refresh_wallet_balances().await {
self.signer = None;View on GitHub (pinned to 2114cf6f76)
Solutions
- Determine the address of the key currently in the env var (e.g. cast wallet address --private-key ...) and set wallet_address in config to that value
- Or update the environment variable to hold the key that controls the configured wallet_address
- Pin the exact env var name per environment in deployment manifests so the wrong key cannot leak across environments
Example fix
# before: env holds test key, config expects mainnet wallet # SIGNER_PRIVATE_KEY=0x<testnet-key> wallet_address = 0x<mainnet-wallet> # after: key and config address match export SIGNER_PRIVATE_KEY=0x<mainnet-key> # cast wallet address -> 0x<mainnet-wallet> # config: wallet_address = 0x<mainnet-wallet>
Defensive patterns
Strategy: try-catch
Validate before calling
// At startup, prove key/address pairing before connecting the client
let key = std::env::var(&config.signer_private_key_env)?;
let signer = PrivateKeySigner::from_str(key.trim())?;
anyhow::ensure!(
signer.address() == config.wallet_address,
"key in '{}' controls {}, config expects {}",
config.signer_private_key_env, signer.address(), config.wallet_address
); Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("does not match configured wallet") => {
// Secrets/coordination issue: page the operator; do not guess which side to change
fatal!("signer/wallet mismatch: {e}");
}
other => other,
} Prevention
- Run a pre-flight check that derives the key's address and diffs it against config
- Store the wallet address WITH the key in your secret manager so they cannot drift
- Never silence this failure to get a session running
When it happens
Trigger: connect() with SIGNER_PRIVATE_KEY-style env var holding a key whose address differs from wallet_address in the config: key rotated in env but config not updated (or vice versa), the env var name resolving to a different environment's key, or a copy/paste of a test key into a mainnet config.
Common situations: Deploying the same config template to multiple environments with per-environment keys; CI and local shells exporting different keys; wallet address taken from an explorer for the wrong account; leading/trailing whitespace is handled (the key is trimmed) but a wrong-length or wrong-key value is not.
Related errors
- Chain ID mismatch at connect: expected {expected_chain_id},
- Signer not initialized; connect the client first
- Signer private key in '{}' is not a valid hex private key
- Authentication failed: {e}
- Timeout waiting for account {account_id} to be registered af
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/6619e12ea63345f3.
Report an issue: GitHub.