nautechsystems/nautilus_trader · critical
Credentials required for execution client
Error message
Credentials required for execution client
What it means
The dYdX execution client requires exchange credentials (a private key) to sign and submit on-chain transactions. During DydxExecClient::new the client builds credentials from config.private_key (and authenticator_ids/network); if the credentials construction returns None, the client refuses to create an execution client and throws this error. Execution (trading) against dYdX cannot proceed without a signing key.
Source
Thrown at crates/adapters/dydx/src/execution/mod.rs:221
config
.proxy_url
.as_ref()
.map(|value| value.expose_secret().to_owned()),
config.network,
Some(retry_config),
)?;
let instrument_cache = http_client.instrument_cache().clone();
let credential = DydxCredential::resolve(
config
.private_key
.as_ref()
.map(|value| value.expose_secret()),
config.network,
config.authenticator_ids.clone(),
)?
.ok_or_else(|| anyhow::anyhow!("Credentials required for execution client"))?;
let ws_client = DydxWebSocketClient::new_private_with_cache(
config.ws_url.clone(),
credential,
core.account_id,
instrument_cache.clone(),
Some(20),
config.transport_backend,
config
.proxy_url
.as_ref()
.map(|value| value.expose_secret().to_owned()),
)
.with_socket_factory(SocketControlFactory::new(core.client_id, Some(*DYDX_VENUE)));
let grpc_client = Arc::new(tokio::sync::RwLock::new(None));
let session_tasks = TaskGroup::new();View on GitHub (pinned to 18893faf8b)
Solutions
- Set private_key in the dYdX execution client config (a valid dYdX-compatible private key), e.g. load from an environment variable at config-build time
- Verify the credential builder (private key + network + authenticator_ids) actually returns Some — check the key format/decoding for the configured network
- If you only need market data, instantiate a data client instead of an execution client
Example fix
// before
let config = DydxExecClientConfig::new(None, network); // private_key missing
// after
let config = DydxExecClientConfig::new(
Some(SecretString::new(std::env::var("DYDX_PRIVATE_KEY")?).into()),
network,
); Defensive patterns
Strategy: validation
Validate before calling
if config.private_key.as_ref().map(|k| k.expose_secret().is_empty()).unwrap_or(true) {
return Err("dYdX execution client requires a private_key in config".into());
} Prevention
- Load the private key from an env var or secret store at config construction and fail fast there
- Use separate configs for data-only vs execution clients and never share the data config with an exec client
- Smoke-test client construction in CI with dummy credentials to catch config gaps early
When it happens
Trigger: Constructing the dYdX execution client with a config whose private_key is None (or whose underlying credential material cannot produce a credential), i.e. running in an execution/live context with only market-data (public) credentials.
Common situations: Config built for data-client-only use reused for an execution client; private_key field omitted or empty in the client config JSON/TOML; key loaded from an env var that is unset; accidentally constructing an exec client in backtest or sandbox where credentials were never provided.
Related errors
- Binance Spot market data mode SBE requires Ed25519 API crede
- Invalid chain ID: {s}
- Lighter execution client requires credentials; set private_k
- Invalid config type for AxExecutionClientFactory. Expected A
- Redis config error: username supplied without password. Eith
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d0be20346fbb3d75.
Report an issue: GitHub.