nautechsystems/nautilus_trader · error
Coinbase credentials unavailable for WS reset
Error message
Coinbase credentials unavailable for WS reset
What it means
Raised in connect() when the client needs to rebuild the Coinbase user WebSocket with API credentials but both config.api_key and config.api_secret are None. CoinbaseIntx credential resolution returns Option; without a key/secret pair the WS reset cannot proceed and connect fails.
Source
Thrown at crates/adapters/coinbase/src/execution.rs:418
// we rebuild the client outright to guarantee clean cmd_tx/out_rx
// pairs and a fresh signal.
if self.ws_user.is_active() || self.ws_user.is_reconnecting() {
log::debug!("Tearing down stale user WS before reconnect");
self.ws_user
.disconnect()
.await
.context("failed to close stale Coinbase user WebSocket")?;
let credential = CoinbaseCredential::resolve(
self.config
.api_key
.as_ref()
.map(|value| value.expose_secret()),
self.config
.api_secret
.as_ref()
.map(|value| value.expose_secret()),
)
.ok_or_else(|| anyhow::anyhow!("Coinbase credentials unavailable for WS reset"))?;
self.ws_user = CoinbaseWebSocketClient::with_credential(
&self.config.ws_url(),
credential,
self.config.transport_backend,
self.config
.proxy_url
.as_ref()
.map(|value| value.expose_secret().to_owned()),
);
}
if self.core.instruments_initialized() {
// Instruments were loaded externally; still propagate the cached
// set to the WS client on reconnect scenarios.
let cached: Vec<InstrumentAny> = self.instruments_cache.values().cloned().collect();
if !cached.is_empty() {
self.ws_user.initialize_instruments(cached).await;
}View on GitHub (pinned to 18893faf8b)
Solutions
- Set api_key and api_secret on CoinbaseExecutionClientConfig (SecretString values).
- Set the COINBASE_API_KEY / COINBASE_API_SECRET environment variables so the config loader picks them up.
- Verify the credentials file/env names match what your node config references.
- If running unauthenticated is intended, use a code path/config that does not require the private WS user channel.
Example fix
// before
let config = CoinbaseExecutionClientConfig { api_key: None, api_secret: None, .. };
// after
let config = CoinbaseExecutionClientConfig {
api_key: Some(SecretString::new(key.into())),
api_secret: Some(SecretString::new(secret.into())),
..
}; Defensive patterns
Strategy: validation
Validate before calling
anyhow::ensure!(
config.api_key.is_some() && config.api_secret.is_some(),
"Coinbase api_key/api_secret required for user WebSocket"
); Type guard
fn has_credentials(config: &CoinbaseExecutionClientConfig) -> bool {
config.api_key.is_some() && config.api_secret.is_some()
} Prevention
- Set COINBASE_API_KEY/COINBASE_API_SECRET in the deployment environment before startup.
- Validate credential presence at config-load time, not at connect time.
- Keep secrets as SecretString and source them from one known env/config location.
When it happens
Trigger: Constructing CoinbaseExecutionClientConfig without api_key/api_secret (relying on env credentials that are not set) and then calling connect() which triggers a WS reset path.
Common situations: Missing COINBASE_API_KEY/COINBASE_API_SECRET environment variables, config built programmatically omitting credentials, or using env-based auth that was removed/renamed.
Related errors
- Binance Spot market data mode SBE requires Ed25519 API crede
- Authentication failed: {e}
- failed to authenticate WebSocket session: {e}
- L3 WebSocket failed to authenticate: {e}
- missing WS auth token
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d93a771661f36533.
Report an issue: GitHub.