nautechsystems/nautilus_trader · critical · anyhow::Error
No wallet credentials found: set wallet_address or private_k
Error message
No wallet credentials found: set wallet_address or private_key in config, or use environment variables (DYDX_WALLET_ADDRESS/DYDX_PRIVATE_KEY for mainnet, DYDX_TESTNET_* for testnet)
What it means
The dYdX client factory (`create`) requires wallet credentials — a `wallet_address`/`private_key` in config or the DYDX_WALLET_ADDRESS/DYDX_PRIVATE_KEY (mainnet) / DYDX_TESTNET_* (testnet) environment variables. If none can be resolved or derived from a private key, it bails with this message.
Source
Thrown at crates/adapters/dydx/src/factories.rs:271
resolve_wallet_address(dydx_config.wallet_address.clone(), dydx_config.network)
{
log::debug!("Using wallet address from config/env: {addr}");
addr
} else if let Some(credential) = DydxCredential::resolve(
dydx_config
.private_key
.as_ref()
.map(|value| value.expose_secret()),
dydx_config.network,
dydx_config.authenticator_ids.clone(),
)? {
log::debug!(
"Derived wallet address from private key: {}",
credential.address
);
credential.address
} else {
anyhow::bail!(
"No wallet credentials found: set wallet_address or private_key in config, or use environment variables (DYDX_WALLET_ADDRESS/DYDX_PRIVATE_KEY for mainnet, DYDX_TESTNET_* for testnet)"
)
};
let client = DydxExecutionClient::new(
core,
adapter_config,
wallet_address,
dydx_config.subaccount_number,
)?;
Ok(Box::new(client))
}
fn name(&self) -> &'static str {
DYDX
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Set private_key (or wallet_address plus key) in the adapter config
- Export DYDX_PRIVATE_KEY and DYDX_WALLET_ADDRESS for mainnet, or DYDX_TESTNET_PRIVATE_KEY/DYDX_TESTNET_WALLET_ADDRESS for testnet
- Verify the environment actually loads them (print presence, not the value, at startup)
- Ensure the testnet flag in config matches which DYDX_TESTNET_* variables you provided
Example fix
// before DydxExecutionClient::new(core, config_without_credentials); // after export DYDX_PRIVATE_KEY=0x... export DYDX_WALLET_ADDRESS=dydx1... // then build config from env let config = DydxExecClientConfig::from_env()?; DydxExecutionClient::new(core, config);
Defensive patterns
Strategy: validation
Validate before calling
let creds_ok = config.private_key.is_some()
|| config.wallet_address.is_some()
|| std::env::var("DYDX_PRIVATE_KEY").is_ok()
|| std::env::var("DYDX_TESTNET_PRIVATE_KEY").is_ok();
if !creds_ok { return Err(anyhow!("no dYdX wallet credentials configured")); } Try / catch
match DydxExecClientFactory::create(core, config) {
Err(e) if e.to_string().contains("No wallet credentials") => configure_credentials_and_retry(),
r => r?,
} Prevention
- Validate credential presence at process startup, before trading
- Use a secret manager or .env loaded deterministically in deployments
- Match mainnet vs testnet env var names to the config's testnet flag
- Never commit keys; inject via CI/CD secrets
When it happens
Trigger: Constructing a DydxExecutionClient via the factory with a config lacking both wallet_address and private_key, and none of the relevant environment variables set in the process.
Common situations: Deploying to an environment where env vars were not injected (CI, Docker without -e flags); .env file not loaded; misspelled variable names; using mainnet vars on a testnet config (or vice versa) so the lookup misses.
Related errors
- Redis config error: username supplied without password. Eith
- {secret_var} is required when {key_var} is provided
- {key_var} is required when {secret_var} is provided
- Both `api_key` and `api_secret` must be provided together
- incomplete Lighter credentials: set {api_key_var}, {api_secr
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/74dc44a13ce52959.
Report an issue: GitHub.