nautechsystems/nautilus_trader · error · anyhow::Error
Binance Spot market data mode SBE requires Ed25519 API…
Error message
Binance Spot market data mode SBE requires Ed25519 API credentials. Set the appropriate env vars for your environment, or provide api_key/api_secret in the data client config
What it means
Binance Spot SBE (Simple Binary Encoding) market data streams require authenticated Ed25519-signed websocket connections. The data client refuses to `connect()` in SBE mode when the underlying websocket client holds no API credentials (`has_credentials()` is false), preventing a doomed connection attempt. Regular JSON market data is public, but SBE requires the key/secret pair.
Solutions
- Provide `api_key` and `api_secret` (Ed25519 keypair credentials) in the data client config
- Export the Binance Ed25519 API credentials as environment variables for your environment
- Verify the credentials are Ed25519 type, not HMAC, as SBE requires Ed25519
- If SBE authentication is not needed, switch `spot_market_data_mode` back to the default JSON mode
- Check that the process environment actually receives the vars (docker --env-file, k8s secret mounting)
Example fix
// before
DataClientConfig { spot_market_data_mode: Sbe, /* no credentials */ }
// after
DataClientConfig {
spot_market_data_mode: Sbe,
api_key: Some(env::var("BINANCE_API_KEY")?),
api_secret: Some(env::var("BINANCE_API_SECRET")?),
} Defensive patterns
Strategy: validation
Validate before calling
fn validate_sbe_credentials(config: &DataClientConfig, env: &Env) -> Result<(), String> {
if config.spot_market_data_mode == BinanceSpotMarketDataMode::Sbe {
let has_cfg = config.api_key.is_some() && config.api_secret.is_some();
let has_env = env::var("BINANCE_API_KEY").is_ok() && env::var("BINANCE_API_SECRET").is_ok();
if !has_cfg && !has_env {
return Err("SBE mode requires Ed25519 api_key/api_secret (config or env)".into());
}
}
Ok()
} Type guard
fn has_credentials(c: &DataClientConfig) -> bool {
c.api_key.as_deref().map_or(false, |k| !k.is_empty())
&& c.api_secret.as_deref().map_or(false, |s| !s.is_empty())
} Try / catch
match data_client.connect().await {
Err(e) if e.to_string().contains("requires Ed25519 API credentials") => {
eprintln!("SBE auth misconfigured: {e:#}");
// fall back to JSON mode or abort startup
}
other => other?,
} Prevention
- Always set Binance Ed25519 API credentials in env or config before enabling SBE mode
- Verify key type is Ed25519 (not HMAC) when creating API keys on Binance
- Forward credential env vars into containers/k8s pods explicitly
- Prefer JSON market data mode when authenticated market data is not needed
When it happens
Trigger: Configuring `spot_market_data_mode = Sbe` on the Binance Spot data client while neither the config provides `api_key`/`api_secret` nor the environment exposes the expected credential env vars, then calling `connect()`.
Common situations: Running locally where env vars (e.g. BINANCE_API_KEY / BINANCE_API_SECRET) are unset because credentials live only in production secrets; switching market data mode to SBE for lower-latency binary feeds without updating the config; container deployments where env vars were not forwarded.
Related errors
- API credentials not configured
- Binance load_ids value
- Binance Spot does not support native GTD; set use_gtd=false…
- Coinbase credentials not available; set COINBASE_API_KEY…
- Coinbase credentials unavailable for WS reset
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5feb5b0016916659.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/spot/data.rs:1493
Ok(())
}
fn dispose(&mut self) -> anyhow::Result<()> {
log::debug!("Disposing {id}", id = self.client_id);
self.stop()
}
async fn connect(&mut self) -> anyhow::Result<()> {
if self.is_connected() && self.session_tasks.is_open() && self.command_tasks.is_open() {
return Ok(());
}
register_binance_custom_data();
if self.spot_market_data_mode == BinanceSpotMarketDataMode::Sbe
&& !self.ws_client.has_credentials()
{
anyhow::bail!(
"Binance Spot market data mode SBE requires Ed25519 API credentials. \
Set the appropriate env vars for your environment, \
or provide api_key/api_secret in the data client config"
);
}
self.prepare_task_groups().await?;
let ws_client = self.ws_client.clone();
let setup_guard =
TaskGroupGuard::new(&[&self.session_tasks, &self.command_tasks], move || {
ws_client.begin_shutdown();
});
Self::refresh_instrument_catalog(
&self.http_client,
&self.config.instrument_provider,
self.config.us,
&self.instruments,View on GitHub (pinned to 18893faf8b)