nautechsystems/nautilus_trader · error
Authentication failed: {e}
Error message
Authentication failed: {e} What it means
During `connect`, after the socket is created the client performs the OKX WebSocket login (HMAC signature auth) for private clients. If authentication fails, the connection is torn down (control deregistered, output channel dropped) and this error is returned; if teardown itself fails, the sibling variant [1039] includes the shutdown error too.
Source
Thrown at crates/adapters/okx/src/websocket/client.rs:893
if let Some(control) = &self.socket_control {
control.register(move || reconnect_handle.request_reconnect());
}
log::debug!("Sent WebSocket client to handler");
if self.credential.is_some()
&& let Err(e) = self.authenticate().await
{
self.handler_tasks.begin_shutdown();
self.request_close().await;
let shutdown_result = self.close_stream_task(Duration::from_secs(2)).await;
if let Some(control) = &self.socket_control {
control.deregister();
}
self.out_rx = None;
match shutdown_result {
Ok(()) => anyhow::bail!("Authentication failed: {e}"),
Err(shutdown_error) => anyhow::bail!(
"Authentication failed: {e}; handler shutdown failed: {shutdown_error}"
),
}
}
rollback.disarm();
Ok(())
}
/// Authenticates the WebSocket session with OKX.
async fn authenticate(&self) -> Result<(), Error> {
let credential = self.credential.as_ref().ok_or_else(|| {
Error::Io(std::io::Error::other(
"API credentials not available to authenticate",
))
})?;
View on GitHub (pinned to 18893faf8b)
Solutions
- Verify `api_key`, `api_secret`, and `api_passphrase` exactly match the OKX API key settings.
- Check system clock sync (NTP) since OKX auth is timestamp-sensitive.
- Confirm the API key has the required permissions (trade/read) and has not been revoked or IP-restricted.
- If the message includes `handler shutdown failed`, also address that shutdown error before retrying.
Example fix
// before: passphrase omitted from config api_key=..., api_secret=... # api_passphrase missing/wrong // after api_key=..., api_secret=..., api_passphrase=<key passphrase>
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight credential sanity check before connecting
if creds.api_key.is_empty() || creds.api_secret.is_empty() || creds.api_passphrase.is_empty() {
return Err(anyhow::anyhow!("refusing to connect: incomplete OKX credentials"));
} Try / catch
match client.connect().await {
Err(e) if e.to_string().starts_with("Authentication failed") => {
log::error!("check OKX api_key/api_secret/api_passphrase and clock sync: {e}");
// do not blind-retry: credentials must be fixed first
}
other => other?,
} Prevention
- Verify the API key, secret, and passphrase in a raw OKX REST call before wiring up the WebSocket client.
- Keep the system clock NTP-synced (auth is timestamp-signed).
- Check the key's permissions and IP allowlist on OKX.
- Do not confuse the key passphrase with the account login password.
When it happens
Trigger: `connect()` on a client constructed with credentials where the OKX login (via the auth endpoint/signature) returns an error — bad key/secret/passphrase, wrong timestamp skew, or network failure during login.
Common situations: Invalid or revoked OKX API key; missing/incorrect passphrase (the key's own passphrase, not the account password); server clock drift breaking the signed timestamp; using private-channel credentials against an endpoint expecting them but with a typo'd secret.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Failed to send WebSocket client to handler: {e}
- Authentication failed: {e}; handler shutdown failed: {shutdo
- failed to set Lighter execution context: {e}
- Bybit data shutdown failed: {}
- failed to re-subscribe Lighter account channels: {error}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5af5daa8b965bfab.
Report an issue: GitHub.